diff options
author | Gustavo Sverzut Barbieri <barbieri@profusion.mobi> | 2016-11-24 00:45:55 -0200 |
---|---|---|
committer | Gustavo Sverzut Barbieri <barbieri@profusion.mobi> | 2016-11-24 00:45:55 -0200 |
commit | 35cdde67d2f07f2413fc093fd8c2d100b2daa0b0 (patch) | |
tree | d17f9f5896bbcbdb2b8ac85d49437e9d6542a24e | |
parent | 92a3361debf36bfab97ba2023679c2e4b4cf2a8c (diff) | |
download | efl-35cdde67d2f07f2413fc093fd8c2d100b2daa0b0.tar.gz |
efl_net_socket_fd: do not spin on fd monitoring.
If we let the user know he can read or write, stop monitoring
otherwise fd handler will constanly report of data to read/write until
its actually done, which would clear the kernel flag.
Since we use "can_read" and "can_write" for that, toggle the callback
connection that manages the actual Ecore_Fd_Handler monitor.
-rw-r--r-- | src/lib/ecore_con/efl_net_socket_fd.c | 48 | ||||
-rw-r--r-- | src/lib/ecore_con/efl_net_socket_fd.eo | 2 |
2 files changed, 45 insertions, 5 deletions
diff --git a/src/lib/ecore_con/efl_net_socket_fd.c b/src/lib/ecore_con/efl_net_socket_fd.c index 9ce046f8d8..c04f2c8e83 100644 --- a/src/lib/ecore_con/efl_net_socket_fd.c +++ b/src/lib/ecore_con/efl_net_socket_fd.c @@ -37,7 +37,7 @@ static void _efl_net_socket_fd_event_read(void *data EINA_UNUSED, const Efl_Event *event) { if (efl_io_closer_closed_get(event->object)) - return; // TODO: unregister READ event + return; efl_io_reader_can_read_set(event->object, EINA_TRUE); } @@ -45,7 +45,7 @@ static void _efl_net_socket_fd_event_write(void *data EINA_UNUSED, const Efl_Event *event) { if (efl_io_closer_closed_get(event->object)) - return; // TODO: unregister WRITE event + return; efl_io_writer_can_write_set(event->object, EINA_TRUE); } @@ -53,7 +53,7 @@ static void _efl_net_socket_fd_event_error(void *data EINA_UNUSED, const Efl_Event *event) { if (efl_io_closer_closed_get(event->object)) - return; // TODO: unregister ERROR event + return; efl_io_writer_can_write_set(event->object, EINA_FALSE); efl_io_reader_can_read_set(event->object, EINA_FALSE); efl_io_reader_eos_set(event->object, EINA_TRUE); @@ -65,8 +65,6 @@ _efl_net_socket_fd_efl_object_finalize(Eo *o, Efl_Net_Socket_Fd_Data *pd EINA_UN o = efl_finalize(efl_super(o, MY_CLASS)); if (!o) return NULL; - // TODO: only register "read" if "can_read" is being monitored? - // TODO: only register "write" if "can_write" is being monitored? efl_event_callback_add(o, EFL_LOOP_FD_EVENT_WRITE, _efl_net_socket_fd_event_write, NULL); efl_event_callback_add(o, EFL_LOOP_FD_EVENT_READ, _efl_net_socket_fd_event_read, NULL); efl_event_callback_add(o, EFL_LOOP_FD_EVENT_ERROR, _efl_net_socket_fd_event_error, NULL); @@ -220,6 +218,26 @@ _efl_net_socket_fd_efl_io_reader_read(Eo *o, Efl_Net_Socket_Fd_Data *pd EINA_UNU return EINVAL; } +EOLIAN static void +_efl_net_socket_fd_efl_io_reader_can_read_set(Eo *o, Efl_Net_Socket_Fd_Data *pd EINA_UNUSED, Eina_Bool value) +{ + Eina_Bool old = efl_io_reader_can_read_get(o); + if (old == value) return; + + efl_io_reader_can_read_set(efl_super(o, MY_CLASS), value); + + if (value) + { + /* stop monitoring the FD, we need to wait the user to read and clear the kernel flag */ + efl_event_callback_del(o, EFL_LOOP_FD_EVENT_READ, _efl_net_socket_fd_event_read, NULL); + } + else + { + /* kernel flag is clear, resume monitoring the FD */ + efl_event_callback_del(o, EFL_LOOP_FD_EVENT_READ, _efl_net_socket_fd_event_read, NULL); + } +} + EOLIAN static Eina_Error _efl_net_socket_fd_efl_io_writer_write(Eo *o, Efl_Net_Socket_Fd_Data *pd EINA_UNUSED, Eina_Slice *ro_slice, Eina_Slice *remaining) { @@ -265,6 +283,26 @@ _efl_net_socket_fd_efl_io_writer_write(Eo *o, Efl_Net_Socket_Fd_Data *pd EINA_UN } EOLIAN static void +_efl_net_socket_fd_efl_io_writer_can_write_set(Eo *o, Efl_Net_Socket_Fd_Data *pd EINA_UNUSED, Eina_Bool value) +{ + Eina_Bool old = efl_io_writer_can_write_get(o); + if (old == value) return; + + efl_io_writer_can_write_set(efl_super(o, MY_CLASS), value); + + if (value) + { + /* stop monitoring the FD, we need to wait the user to write and clear the kernel flag */ + efl_event_callback_del(o, EFL_LOOP_FD_EVENT_WRITE, _efl_net_socket_fd_event_write, NULL); + } + else + { + /* kernel flag is clear, resume monitoring the FD */ + efl_event_callback_del(o, EFL_LOOP_FD_EVENT_WRITE, _efl_net_socket_fd_event_write, NULL); + } +} + +EOLIAN static void _efl_net_socket_fd_efl_net_socket_address_local_set(Eo *o EINA_UNUSED, Efl_Net_Socket_Fd_Data *pd, const char *address) { eina_stringshare_replace(&pd->address_local, address); diff --git a/src/lib/ecore_con/efl_net_socket_fd.eo b/src/lib/ecore_con/efl_net_socket_fd.eo index 8df4c75b75..b5973f9578 100644 --- a/src/lib/ecore_con/efl_net_socket_fd.eo +++ b/src/lib/ecore_con/efl_net_socket_fd.eo @@ -37,7 +37,9 @@ class Efl.Net.Socket.Fd (Efl.Loop.Fd, Efl.Io.Reader.Fd, Efl.Io.Writer.Fd, Efl.Io Efl.Io.Closer.close; Efl.Io.Closer.closed.get; Efl.Io.Reader.read; + Efl.Io.Reader.can_read.set; Efl.Io.Writer.write; + Efl.Io.Writer.can_write.set; Efl.Net.Socket.address_local; Efl.Net.Socket.address_remote; } |