summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric Bail <cedric@osg.samsung.com>2016-07-08 14:00:43 -0700
committerCedric BAIL <cedric@osg.samsung.com>2016-09-08 14:51:56 -0700
commit2e178e09c666aeca48601e0bd730cb13bdbb3238 (patch)
treecd35c455bd619bfb96e20c1a83d4490de8eac306
parentb9f679f23c24f5a6ace2491c685f82e1317c15c4 (diff)
downloadefl-2e178e09c666aeca48601e0bd730cb13bdbb3238.tar.gz
ecore: add support for optional futures.
-rw-r--r--src/lib/ecore/ecore_main.c21
-rw-r--r--src/lib/ecore/ecore_private.h3
-rw-r--r--src/lib/ecore/efl_promise.c19
3 files changed, 41 insertions, 2 deletions
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index 851d6fe2e1..3a34580155 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 e476b32700..f31b2f560e 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 5a03cee90d..38e1f2f88d 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