From 5c961bba9b3c724764cbc915a3ed9c1df918d4c8 Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Wed, 23 Nov 2016 03:11:26 -0200 Subject: [PATCH] efl_io_copier: add flush method. This method will force a read-write cycle and returns if it's fully done or not. It may be used to force data to be written before a handle is deleted (when one can't wait for the data to be written asynchronously). --- src/lib/ecore/efl_io_copier.c | 37 ++++++++++++++++++++++++++++++++++ src/lib/ecore/efl_io_copier.eo | 25 +++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/lib/ecore/efl_io_copier.c b/src/lib/ecore/efl_io_copier.c index d304dfe4f8..a47d3dfcaf 100644 --- a/src/lib/ecore/efl_io_copier.c +++ b/src/lib/ecore/efl_io_copier.c @@ -704,6 +704,43 @@ _efl_io_copier_inactivity_timeout_get(Eo *o EINA_UNUSED, Efl_Io_Copier_Data *pd) return pd->inactivity_timeout; } +EOLIAN static Eina_Bool +_efl_io_copier_flush(Eo *o, Efl_Io_Copier_Data *pd) +{ + uint64_t old_read = pd->progress.read; + uint64_t old_written = pd->progress.written; + uint64_t old_total = pd->progress.total; + + _COPIER_DBG(o, pd); + + if (pd->source && !efl_io_reader_eos_get(pd->source)) + _efl_io_copier_read(o, pd); + + if (pd->destination) + _efl_io_copier_write(o, pd); + + if ((old_read != pd->progress.read) || + (old_written != pd->progress.written) || + (old_total != pd->progress.total)) + { + efl_event_callback_call(o, EFL_IO_COPIER_EVENT_PROGRESS, NULL); + _efl_io_copier_inactivity_timeout_reschedule(o, pd); + } + + if (!pd->source || efl_io_reader_eos_get(pd->source)) + { + if ((!pd->done) && + ((!pd->destination) || (eina_binbuf_length_get(pd->buf) == 0))) + { + pd->done = EINA_TRUE; + if (pd->inactivity_timer) efl_future_cancel(pd->inactivity_timer); + efl_event_callback_call(o, EFL_IO_COPIER_EVENT_DONE, NULL); + } + } + + return pd->done; +} + EOLIAN static Eo * _efl_io_copier_efl_object_constructor(Eo *o, Efl_Io_Copier_Data *pd) { diff --git a/src/lib/ecore/efl_io_copier.eo b/src/lib/ecore/efl_io_copier.eo index a5e07ac280..c19e3b2c4b 100644 --- a/src/lib/ecore/efl_io_copier.eo +++ b/src/lib/ecore/efl_io_copier.eo @@ -112,6 +112,31 @@ class Efl.Io.Copier (Efl.Loop_User, Efl.Io.Closer) { ]] return: free(own(ptr(Eina.Binbuf)), eina_binbuf_free) @warn_unused; [[Binbuf]] } + + flush { + [[Forces reading from source and writing to destination. + + This executes a single read->write cycle, if more data + could be read from source (ie: not EOS) or not all data + was written to destination, then $false is + returned. Then to forcefully drain source and write all + contents to destination, use in a loop until it returns + $true. + + The return value matches "done" event, that is, when + $true is returned, the "done" event is emitted. + + This function may also emit "progress" and "error" + events. + + \@note this function may block the main loop execution + until operations complete! This is bad for usability, as + user interface or other operations may freeze. A better + approach is to operate asynchronously and wait for + "done" event. + ]] + return: bool(true); + } } events {