cedric pushed a commit to branch master.

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

commit cd6a8aa6b3ed49c7d246bad27837a306acff9630
Author: Cedric Bail <ced...@osg.samsung.com>
Date:   Fri Jul 8 14:00:43 2016 -0700

    ecore: add support for optional futures.
---
 src/lib/ecore/ecore_main.c    | 21 +++++++++++++++++++++
 src/lib/ecore/ecore_private.h |  3 +++
 src/lib/ecore/efl_promise.c   | 19 +++++++++++++++++--
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index 851d6fe..3a34580 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -275,6 +275,7 @@ static void _ecore_main_win32_handlers_cleanup(void);
 
 int in_main_loop = 0;
 
+static Eina_List *_pending_futures = NULL;
 static unsigned char _ecore_exit_code = 0;
 static int do_quit = 0;
 static Ecore_Fd_Handler *fd_handlers = NULL;
@@ -2226,8 +2227,14 @@ static void
 _ecore_main_loop_iterate_internal(int once_only)
 {
    double next_time = -1.0;
+   Eo *f;
 
    in_main_loop++;
+
+   /* destroy all optional futures */
+   EINA_LIST_FREE(_pending_futures, f)
+     efl_del(f);
+
    /* expire any timers */
    _efl_loop_timer_expired_timers_call(_ecore_time_loop_time);
 
@@ -2905,6 +2912,20 @@ ecore_loop_arguments_send(int argc, const char **argv)
 static void _efl_loop_timeout_force_cancel_cb(void *data, const Efl_Event 
*event EINA_UNUSED);
 static void _efl_loop_timeout_cb(void *data, const Efl_Event *event 
EINA_UNUSED);
 
+// Only one main loop handle for now
+void
+ecore_loop_future_register(Efl_Loop *l EINA_UNUSED, Efl_Future *f)
+{
+   _pending_futures = eina_list_append(_pending_futures, f);
+}
+
+void
+ecore_loop_future_unregister(Efl_Loop *l EINA_UNUSED, Efl_Future *f)
+{
+   _pending_futures = eina_list_remove(_pending_futures, f);
+}
+
+
 EFL_CALLBACKS_ARRAY_DEFINE(timeout,
                           { EFL_LOOP_TIMER_EVENT_TICK, _efl_loop_timeout_cb },
                           { EFL_EVENT_DEL, _efl_loop_timeout_force_cancel_cb 
});
diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h
index e476b32..f31b2f5 100644
--- a/src/lib/ecore/ecore_private.h
+++ b/src/lib/ecore/ecore_private.h
@@ -371,6 +371,9 @@ extern Efl_Version _app_efl_version;
 #define ECORE_PARENT_CLASS ecore_parent_class_get()
 EAPI const Efl_Class *ecore_parent_class_get(void) EINA_CONST;
 
+void ecore_loop_future_register(Efl_Loop *l EINA_UNUSED, Efl_Future *f);
+void ecore_loop_future_unregister(Efl_Loop *l EINA_UNUSED, Efl_Future *f);
+
 // access to direct input cb
 #define ECORE_EVAS_INTERNAL
 
diff --git a/src/lib/ecore/efl_promise.c b/src/lib/ecore/efl_promise.c
index 5a03cee..38e1f2f 100644
--- a/src/lib/ecore/efl_promise.c
+++ b/src/lib/ecore/efl_promise.c
@@ -6,8 +6,6 @@
 
 #include "ecore_private.h"
 
-// FIXME: handle self destruction when back in the main loop
-
 typedef struct _Efl_Promise_Data Efl_Promise_Data;
 typedef struct _Efl_Promise_Msg Efl_Promise_Msg;
 
@@ -77,6 +75,7 @@ struct _Efl_Loop_Future_Data
    Eina_Bool fulfilled : 1;
    Eina_Bool death : 1;
    Eina_Bool delayed : 1;
+   Eina_Bool optional : 1;
 };
 
 static void
@@ -178,6 +177,12 @@ _efl_loop_future_prepare_events(Efl_Loop_Future_Data *pd, 
Eina_Bool progress)
 {
    if (!pd->promise) return ;
 
+   if (pd->optional)
+     {
+        pd->optional = EINA_FALSE;
+        ecore_loop_future_unregister(efl_provider_find(pd->self, 
EFL_LOOP_CLASS), pd->self);
+     }
+
    pd->promise->set.future = EINA_TRUE;
    if (progress)
      pd->promise->set.progress = EINA_TRUE;
@@ -288,6 +293,9 @@ _efl_loop_future_efl_object_constructor(Eo *obj, 
Efl_Loop_Future_Data *pd)
    obj = efl_constructor(efl_super(obj, EFL_LOOP_FUTURE_CLASS));
 
    pd->self = obj;
+   pd->optional = EINA_TRUE;
+
+   ecore_loop_future_register(efl_provider_find(obj, EFL_LOOP_CLASS), obj);
 
    efl_del_intercept_set(obj, _efl_loop_future_intercept);
 
@@ -318,6 +326,13 @@ _efl_loop_future_efl_object_destructor(Eo *obj, 
Efl_Loop_Future_Data *pd)
         pd->message = NULL;
      }
 
+   // Stop the main loop handler that would destroy this optional future
+   if (pd->optional)
+     {
+        pd->optional = EINA_FALSE;
+        ecore_loop_future_unregister(efl_provider_find(pd->self, 
EFL_LOOP_CLASS), pd->self);
+     }
+
    efl_destructor(efl_super(obj, EFL_LOOP_FUTURE_CLASS));
 
    // Disconnect from the promise

-- 


Reply via email to