cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=150bc0fa14d7df39254173980de5c86085b1ceff

commit 150bc0fa14d7df39254173980de5c86085b1ceff
Author: Cedric BAIL <cedric.b...@free.fr>
Date:   Fri Mar 15 14:38:24 2019 -0700

    eio: work around the lack of integration between Ecore_Thread and 
Eina_Future.
    
    Ecore_Thread excpect resolution of the error and done case to be 
instantaneous,
    while Eina_Future default scheduler linked with Ecore main loop is build 
around
    asynchronous answer. This create a lot of potential. A better patch would be
    to provide an Ecore_Thread helper that does the integration properly. Sadly
    we are in release now, so this is basically what an helper would do, but
    contained inside Efl_Io_Manager.
    
    This also solve the same problem as D7970 and D8053, but it should avoid its
    side effect.
    
    Reviewed-by: YeongJong Lee <yj34....@samsung.com>
    Differential Revision: https://phab.enlightenment.org/D8371
---
 src/lib/eio/efl_io_manager.c | 120 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 111 insertions(+), 9 deletions(-)

diff --git a/src/lib/eio/efl_io_manager.c b/src/lib/eio/efl_io_manager.c
index 3509bc6a63..3bb05634be 100644
--- a/src/lib/eio/efl_io_manager.c
+++ b/src/lib/eio/efl_io_manager.c
@@ -49,6 +49,102 @@ struct _Job_Closure
    Efl_Io_Manager_Direct_Ls_Func direct_func;  // Used when dispatching direct 
ls funcs.
 };
 
+/* Future have to be resolved right away in the thread context */
+typedef struct _Eio_Future_Entry Eio_Future_Entry;
+struct _Eio_Future_Entry
+{
+   Eina_Future_Schedule_Entry base;
+   Eina_Future_Scheduler_Cb cb;
+   Eina_Future *future;
+   Eina_Value value;
+};
+
+static Eina_Trash *eio_entry_trash = NULL;
+static unsigned int eio_entry_trash_count = 0;
+static Eina_List *entries = NULL;
+
+static Eina_Future_Schedule_Entry *
+eio_future_schedule(Eina_Future_Scheduler *sched,
+                    Eina_Future_Scheduler_Cb cb,
+                    Eina_Future *future,
+                    Eina_Value value)
+{
+   Eio_Future_Entry *ef = NULL;
+
+   if (!eio_entry_trash)
+     {
+        ef = calloc(1, sizeof (Eio_Future_Entry));
+        if (!ef) return NULL;
+     }
+   else
+     {
+        ef = eina_trash_pop(&eio_entry_trash);
+        eio_entry_trash_count--;
+     }
+   ef->base.scheduler = sched;
+   ef->cb = cb;
+   ef->future = future;
+   ef->value = value;
+
+   entries = eina_list_append(entries, ef);
+
+   return &ef->base;
+}
+
+static void
+eio_future_free(Eio_Future_Entry *ef)
+{
+   entries = eina_list_remove(entries, ef);
+
+   if (eio_entry_trash_count > 8)
+     {
+        free(ef);
+        return ;
+     }
+   eina_trash_push(&eio_entry_trash, ef);
+   eio_entry_trash_count++;
+}
+
+static void
+eio_future_recall(Eina_Future_Schedule_Entry *se)
+{
+   Eio_Future_Entry *ef = (Eio_Future_Entry *) se;
+
+   eina_value_flush(&ef->value);
+   eio_future_free(ef);
+}
+
+static Eina_Future_Scheduler eio_future_scheduler = {
+   .schedule = eio_future_schedule,
+   .recall = eio_future_recall,
+};
+
+static void
+eio_dummy_cancel(void *data EINA_UNUSED, const Eina_Promise *p EINA_UNUSED)
+{
+}
+
+static void
+eio_process_entry(void)
+{
+   Eio_Future_Entry *ef;
+
+   while (entries)
+     {
+        ef = eina_list_data_get(entries);
+        ef->cb(ef->future, ef->value);
+        eio_future_free(ef);
+     }
+}
+
+static Eina_Promise *
+eio_promise_new(const Eo *obj)
+{
+   if (!efl_alive_get(obj)) return NULL;
+
+   return eina_promise_new(&eio_future_scheduler, eio_dummy_cancel, NULL);
+}
+
 /* Helper functions */
 static void
 _future_file_done_cb(void *data, Eio_File *handler)
@@ -56,6 +152,7 @@ _future_file_done_cb(void *data, Eio_File *handler)
    Eina_Promise *p = data;
 
    eina_promise_resolve(p, eina_value_uint64_init(handler->length));
+   eio_process_entry();
 }
 
 static void
@@ -67,6 +164,7 @@ _future_file_error_cb(void *data,
 
    // error == 0 -> promise was cancelled, no need to reject it anymore
    if (error != 0) eina_promise_reject(p, error);
+   eio_process_entry();
 }
 
 /* Basic listing callbacks */
@@ -119,7 +217,7 @@ _efl_io_manager_direct_ls(const Eo *obj,
    Eina_Future *future;
    Eio_File *h;
 
-   p = efl_loop_promise_new(obj);
+   p = eio_promise_new(obj);
    if (!p) return NULL;
    future = eina_future_new(p);
 
@@ -161,7 +259,7 @@ _efl_io_manager_stat_ls(const Eo *obj,
    Eina_Future *future;
    Eio_File *h;
 
-   p = efl_loop_promise_new(obj);
+   p = eio_promise_new(obj);
    if (!p) return NULL;
    future = eina_future_new(p);
 
@@ -202,7 +300,7 @@ _efl_io_manager_ls(const Eo *obj,
    Eina_Future *future;
    Eio_File *h;
 
-   p = efl_loop_promise_new(obj);
+   p = eio_promise_new(obj);
    if (!p) return NULL;
    future = eina_future_new(p);
 
@@ -236,12 +334,14 @@ _file_stat_done_cb(void *data, Eio_File *handle 
EINA_UNUSED, const Eina_Stat *st
      goto on_error;
 
    eina_promise_resolve(p, r);
+   eio_process_entry();
 
    return ;
 
  on_error:
    eina_value_flush(&r);
    eina_promise_reject(p, eina_error_get());
+   eio_process_entry();
 }
 
 static Eina_Future *
@@ -253,7 +353,7 @@ _efl_io_manager_stat(const Eo *obj,
    Eina_Future *future;
    Eio_File *h;
 
-   p = efl_loop_promise_new(obj);
+   p = eio_promise_new(obj);
    if (!p) return NULL;
    future = eina_future_new(p);
 
@@ -281,7 +381,7 @@ _efl_io_manager_xattr_ls(const Eo *obj,
    Eina_Future *future;
    Eio_File *h;
 
-   p = efl_loop_promise_new(obj);
+   p = eio_promise_new(obj);
    if (!p) return NULL;
    future = eina_future_new(p);
 
@@ -317,6 +417,7 @@ _future_file_done_data_cb(void *data, Eio_File *handler 
EINA_UNUSED, const char
    eina_value_setup(&v, EINA_VALUE_TYPE_BLOB);
    eina_value_set(&v, &blob);
    eina_promise_resolve(p, v);
+   eio_process_entry();
 }
 
 static Eina_Future *
@@ -331,7 +432,7 @@ _efl_io_manager_xattr_set(Eo *obj,
    Eina_Future *future;
    Eio_File *h;
 
-   p = efl_loop_promise_new(obj);
+   p = eio_promise_new(obj);
    if (!p) return NULL;
    future = eina_future_new(p);
 
@@ -360,7 +461,7 @@ _efl_io_manager_xattr_get(const Eo *obj,
    Eina_Future *future;
    Eio_File *h;
 
-   p = efl_loop_promise_new(obj);
+   p = eio_promise_new(obj);
    if (!p) return NULL;
    future = eina_future_new(p);
 
@@ -385,6 +486,7 @@ _future_file_open_cb(void *data, Eio_File *handler 
EINA_UNUSED, Eina_File *file)
    eina_value_setup(&v, EINA_VALUE_TYPE_FILE);
    eina_value_set(&v, file);
    eina_promise_resolve(p, v);
+   eio_process_entry();
 }
 
 static Eina_Future *
@@ -397,7 +499,7 @@ _efl_io_manager_open(const Eo *obj,
    Eina_Future *future;
    Eio_File *h;
 
-   p = efl_loop_promise_new(obj);
+   p = eio_promise_new(obj);
    if (!p) return NULL;
    future = eina_future_new(p);
 
@@ -422,7 +524,7 @@ _efl_io_manager_close(const Eo *obj,
    Eina_Future *future;
    Eio_File *h;
 
-   p = efl_loop_promise_new(obj);
+   p = eio_promise_new(obj);
    if (!p) return NULL;
    future = eina_future_new(p);
 

-- 


Reply via email to