From f57316655cf5bc7de0e8278bc48e252296d485ee Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Fri, 21 Oct 2016 09:24:50 -0200 Subject: [PATCH] efl_net_server_fd: allows custom socket 'read' event handling. This allows UDP to reimplement it using recvfrom() instead of accept(). --- src/lib/ecore_con/efl_net_server_fd.c | 75 +++++++++++++++++----------------- src/lib/ecore_con/efl_net_server_fd.eo | 15 +++++++ 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/src/lib/ecore_con/efl_net_server_fd.c b/src/lib/ecore_con/efl_net_server_fd.c index c3e9ee2..a6383f6 100644 --- a/src/lib/ecore_con/efl_net_server_fd.c +++ b/src/lib/ecore_con/efl_net_server_fd.c @@ -61,43 +61,7 @@ efl_net_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, Eina_Bool clo static void _efl_net_server_fd_event_read(void *data EINA_UNUSED, const Efl_Event *event) { - Eo *o = event->object; - unsigned int count, limit; - Eina_Bool reject_excess, do_reject = EINA_FALSE; - struct sockaddr_storage addr; - int client, fd; - socklen_t addrlen; - - count = efl_net_server_clients_count_get(o); - efl_net_server_clients_limit_get(o, &limit, &reject_excess); - - if ((limit > 0) && (count >= limit)) - { - if (!reject_excess) - { - // TODO: disconnect 'read' so stops calling? - return; - } - do_reject = EINA_TRUE; - } - - fd = efl_loop_fd_get(o); - - addrlen = sizeof(addr); - client = efl_net_accept4(fd, (struct sockaddr *)&addr, &addrlen, - efl_net_server_fd_close_on_exec_get(o)); - if (client < 0) - { - Eina_Error err = errno; - ERR("accept(%d): %s", fd, strerror(errno)); - efl_event_callback_call(o, EFL_NET_SERVER_EVENT_ERROR, &err); - return; - } - - if (do_reject) - efl_net_server_fd_client_reject(o, client); - else - efl_net_server_fd_client_add(o, client); + efl_net_server_fd_process_incoming_data(event->object); } static void @@ -389,4 +353,41 @@ _efl_net_server_fd_family_get(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd) return pd->family; } +EOLIAN static void +_efl_net_server_fd_process_incoming_data(Eo *o, Efl_Net_Server_Fd_Data *pd) +{ + Eina_Bool do_reject = EINA_FALSE; + struct sockaddr_storage addr; + int client, fd; + socklen_t addrlen; + + if ((pd->clients_limit > 0) && (pd->clients_count >= pd->clients_limit)) + { + if (!pd->clients_reject_excess) + { + // TODO: disconnect 'read' so stops calling? + return; + } + do_reject = EINA_TRUE; + } + + fd = efl_loop_fd_get(o); + + addrlen = sizeof(addr); + client = efl_net_accept4(fd, (struct sockaddr *)&addr, &addrlen, + efl_net_server_fd_close_on_exec_get(o)); + if (client < 0) + { + Eina_Error err = errno; + ERR("accept(%d): %s", fd, strerror(errno)); + efl_event_callback_call(o, EFL_NET_SERVER_EVENT_ERROR, &err); + return; + } + + if (do_reject) + efl_net_server_fd_client_reject(o, client); + else + efl_net_server_fd_client_add(o, client); +} + #include "efl_net_server_fd.eo.c" diff --git a/src/lib/ecore_con/efl_net_server_fd.eo b/src/lib/ecore_con/efl_net_server_fd.eo index 7b082e6..df86c54 100644 --- a/src/lib/ecore_con/efl_net_server_fd.eo +++ b/src/lib/ecore_con/efl_net_server_fd.eo @@ -59,6 +59,21 @@ class Efl.Net.Server.Fd (Efl.Loop.Fd, Efl.Net.Server) { } } + process_incoming_data @protected { + [[When the socket has data to be read, process it. + + By default this method will call accept() and then + decide if @.client_add or @.client_reject must be + executed, however it may be replaced with something + else, such as in SOCK_DGRAM (UDP) there is no accept(), + only recvfrom(). + + It is called straight from @Efl.Loop.Fd "read" event + handler and is provided as a method to allow easy + extending of the class for various purposes. + ]] + } + client_add @protected @virtual_pure { [[Accept a new client, should emit "client,add". -- 2.7.4