summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-12-07 17:39:01 -0200
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-12-08 11:40:45 -0200
commit994d66513f69b2feb506970d6e6fb7d204cb8f1e (patch)
tree54a424f206b3a3282f4fbd47948557ec3db37a4a
parentc33ed61e1735020953b67f1049c11cedd51950dc (diff)
downloadefl-994d66513f69b2feb506970d6e6fb7d204cb8f1e.tar.gz
efl_io_buffered_stream: better detection of 'finished' state.
When used with sockets, if it's EOS (ie: remote peer terminated the connection), but not closed, then it would not emit 'finished' event. Now it does.
-rw-r--r--src/lib/ecore/efl_io_buffered_stream.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/lib/ecore/efl_io_buffered_stream.c b/src/lib/ecore/efl_io_buffered_stream.c
index 69ea69c35e..6d58e67395 100644
--- a/src/lib/ecore/efl_io_buffered_stream.c
+++ b/src/lib/ecore/efl_io_buffered_stream.c
@@ -21,6 +21,7 @@ typedef struct
Eina_Bool can_read;
Eina_Bool can_write;
Eina_Bool is_closer;
+ Eina_Bool is_finished;
} Efl_Io_Buffered_Stream_Data;
#define MY_CLASS EFL_IO_BUFFERED_STREAM_CLASS
@@ -98,11 +99,21 @@ _efl_io_buffered_stream_sender_done(void *data, const Efl_Event *event EINA_UNUS
{
Eo *o = data;
Efl_Io_Buffered_Stream_Data *pd = efl_data_scope_get(o, MY_CLASS);
+ size_t pending = pd->receiver ? efl_io_copier_pending_size_get(pd->receiver) : 0;
+
efl_ref(o);
efl_event_callback_call(o, EFL_IO_BUFFERED_STREAM_EVENT_PROGRESS, NULL);
efl_event_callback_call(o, EFL_IO_BUFFERED_STREAM_EVENT_WRITE_FINISHED, NULL);
- if (efl_io_copier_done_get(pd->receiver))
- efl_event_callback_call(o, EFL_IO_BUFFERED_STREAM_EVENT_FINISHED, NULL);
+ if ((pending == 0) || efl_io_copier_done_get(pd->receiver))
+ {
+ if (!pd->is_finished)
+ {
+ pd->is_finished = EINA_TRUE;
+ efl_event_callback_call(o, EFL_IO_BUFFERED_STREAM_EVENT_FINISHED, NULL);
+ }
+ }
+ else
+ DBG("%p sender done, waiting for receiver to process %zd to call it 'finished'", o, pending);
efl_unref(o);
}
@@ -269,6 +280,8 @@ _efl_io_buffered_stream_efl_io_reader_eos_get(Eo *o EINA_UNUSED, Efl_Io_Buffered
EOLIAN static void
_efl_io_buffered_stream_efl_io_reader_eos_set(Eo *o, Efl_Io_Buffered_Stream_Data *pd, Eina_Bool is_eos)
{
+ size_t pending = pd->sender ? efl_io_copier_pending_size_get(pd->sender) : 0;
+
EINA_SAFETY_ON_TRUE_RETURN(efl_io_closer_closed_get(o));
if (pd->eos == is_eos) return;
pd->eos = is_eos;
@@ -278,8 +291,16 @@ _efl_io_buffered_stream_efl_io_reader_eos_set(Eo *o, Efl_Io_Buffered_Stream_Data
efl_event_callback_call(o, EFL_IO_BUFFERED_STREAM_EVENT_PROGRESS, NULL);
efl_event_callback_call(o, EFL_IO_READER_EVENT_EOS, NULL);
efl_event_callback_call(o, EFL_IO_BUFFERED_STREAM_EVENT_READ_FINISHED, NULL);
- if (efl_io_copier_done_get(pd->sender))
- efl_event_callback_call(o, EFL_IO_BUFFERED_STREAM_EVENT_FINISHED, NULL);
+ if ((pending == 0) || efl_io_copier_done_get(pd->sender))
+ {
+ if (!pd->is_finished)
+ {
+ pd->is_finished = EINA_TRUE;
+ efl_event_callback_call(o, EFL_IO_BUFFERED_STREAM_EVENT_FINISHED, NULL);
+ }
+ }
+ else
+ DBG("%p eos, waiting for sender process %zd to call 'finished'", o, pending);
efl_unref(o);
}