remove elgacy ecore event usage in futures that limit to mainloop only
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>
Wed, 27 Dec 2017 16:19:52 +0000 (01:19 +0900)
committerWonki Kim <wonki_.kim@samsung.com>
Wed, 10 Jan 2018 11:08:13 +0000 (20:08 +0900)
also eina_procmis was not threadsafe so cannto use loops in different
threads at all until this was made safe. needed to disable the old
ecore_event using code in for ecore futures and create a new efl loop
message future and handler instead ... but now a quick experiment with
multiple loops in 10 threads plus mainloop have timers at least work.
i need to test more like fd handlers etc etc. but it's a step.

13 files changed:
src/Makefile_Ecore.am
src/lib/ecore/Ecore_Eo.h
src/lib/ecore/ecore_events.c
src/lib/ecore/ecore_private.h
src/lib/ecore/ecore_timer.c
src/lib/ecore/efl_loop.c
src/lib/ecore/efl_loop_message.eo
src/lib/ecore/efl_loop_message_future.c [new file with mode: 0644]
src/lib/ecore/efl_loop_message_future.eo [new file with mode: 0644]
src/lib/ecore/efl_loop_message_future_handler.c [new file with mode: 0644]
src/lib/ecore/efl_loop_message_future_handler.eo [new file with mode: 0644]
src/lib/ecore/efl_loop_message_handler.c
src/lib/eina/eina_promise.c

index 7ef3b74..8612bb2 100644 (file)
@@ -38,6 +38,8 @@ ecore_eolian_files_public = \
 
 ecore_eolian_files = \
        $(ecore_eolian_files_public) \
+        lib/ecore/efl_loop_message_future_handler.eo \
+        lib/ecore/efl_loop_message_future.eo \
        lib/ecore/efl_promise.eo \
        lib/ecore/efl_model_item.eo \
        lib/ecore/efl_model_container.eo \
@@ -97,6 +99,8 @@ lib/ecore/efl_loop_fd.c \
 lib/ecore/efl_loop_handler.c \
 lib/ecore/efl_loop_message.c \
 lib/ecore/efl_loop_message_handler.c \
+lib/ecore/efl_loop_message_future.c \
+lib/ecore/efl_loop_message_future_handler.c \
 lib/ecore/efl_io_closer_fd.c \
 lib/ecore/efl_io_positioner_fd.c \
 lib/ecore/efl_io_reader_fd.c \
index ec690a7..211c12c 100644 (file)
@@ -36,6 +36,9 @@ extern "C" {
 #include "ecore_event_message.eo.h"
 #include "ecore_event_message_handler.eo.h"
 
+#include "efl_loop_message_future.eo.h"
+#include "efl_loop_message_future_handler.eo.h"
+
 /**
  * @ingroup Ecore_MainLoop_Group
  *
index 3adbe04..3911abe 100644 (file)
@@ -12,16 +12,16 @@ typedef struct _Ecore_Future_Schedule_Entry
    Eina_Future_Schedule_Entry base;
    Eina_Future_Scheduler_Cb cb;
    Eina_Future *future;
-   Ecore_Event *event;
+   Eo *event;
    Eina_Value value;
 } Ecore_Future_Schedule_Entry;
 
 //////
 // XXX: still using legacy ecore events
-static Ecore_Event_Handler *future_handler             = NULL;
+//static Ecore_Event_Handler *future_handler             = NULL;
 static Eina_Bool            shutting_down              = EINA_FALSE;
 static Eina_Mempool        *mp_future_schedule_entry   = NULL;
-static int                  ECORE_EV_FUTURE_ID         = -1;
+//static int                  ECORE_EV_FUTURE_ID         = -1;
 //
 //////
 
@@ -71,17 +71,6 @@ ecore_event_add(int          type,
    return (Ecore_Event *)msg;
 }
 
-static void
-_event_del_cb(void *data, const Efl_Event *ev)
-{
-   Ecore_Future_Schedule_Entry *entry = data;
-   if ((ev->object == (Eo *) entry->event) && entry->future)
-     {
-        eina_future_cancel(entry->future);
-        eina_value_flush(&entry->value);
-     }
-}
-
 EAPI void *
 ecore_event_del(Ecore_Event *event)
 {
@@ -127,8 +116,11 @@ ecore_event_current_event_get(void)
    return ecore_event_message_handler_current_event_get(_event_msg_handler);
 }
 
+/* XXX:
 static Eina_Bool
-ecore_future_dispatched(void *data EINA_UNUSED, int type  EINA_UNUSED, void *event)
+ecore_future_dispatched(void *data EINA_UNUSED,
+                        int type EINA_UNUSED,
+                        void *event)
 {
    Ecore_Future_Schedule_Entry *entry = event;
    EINA_SAFETY_ON_NULL_RETURN_VAL(entry, EINA_FALSE);
@@ -139,7 +131,8 @@ ecore_future_dispatched(void *data EINA_UNUSED, int type  EINA_UNUSED, void *eve
 }
 
 static void
-ecore_future_free(void *user_data, void *func_data EINA_UNUSED)
+ecore_future_free(void *user_data,
+                  void *func_data EINA_UNUSED)
 {
    Ecore_Future_Schedule_Entry *entry = user_data;
    if (entry->event)
@@ -149,10 +142,35 @@ ecore_future_free(void *user_data, void *func_data EINA_UNUSED)
      }
    eina_mempool_free(mp_future_schedule_entry, entry);
 }
+*/
+
+static void
+_future_dispatch_cb(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+   Ecore_Future_Schedule_Entry *entry = data;
+   entry->event = NULL;
+   entry->cb(entry->future, entry->value);
+}
+
+static void
+_event_del_cb(void *data, const Efl_Event *ev)
+{
+   Ecore_Future_Schedule_Entry *entry = data;
+   if ((ev->object == (Eo *) entry->event) && entry->future)
+     {
+        eina_future_cancel(entry->future);
+        eina_value_flush(&entry->value);
+     }
+   eina_mempool_free(mp_future_schedule_entry, entry);
+}
 
 static Eina_Future_Schedule_Entry *
-ecore_future_schedule(Eina_Future_Scheduler *sched, Eina_Future_Scheduler_Cb cb, Eina_Future *future, Eina_Value value)
+ecore_future_schedule(Eina_Future_Scheduler *sched,
+                      Eina_Future_Scheduler_Cb cb,
+                      Eina_Future *future,
+                      Eina_Value value)
 {
+   Efl_Loop_Future_Scheduler *loopsched = (Efl_Loop_Future_Scheduler *)sched;
    Ecore_Future_Schedule_Entry *entry;
 
    entry = eina_mempool_malloc(mp_future_schedule_entry, sizeof(*entry));
@@ -161,9 +179,19 @@ ecore_future_schedule(Eina_Future_Scheduler *sched, Eina_Future_Scheduler_Cb cb,
    entry->cb = cb;
    entry->future = future;
    entry->value = value;
-   entry->event = ecore_event_add(ECORE_EV_FUTURE_ID, entry, ecore_future_free, entry);
+   entry->event = efl_loop_message_future_handler_message_type_add
+     (loopsched->loop_data->future_message_handler);
    EINA_SAFETY_ON_NULL_GOTO(entry->event, err);
-   efl_event_callback_add((Eo *) entry->event, EFL_EVENT_DEL, _event_del_cb, entry);
+   efl_loop_message_future_data_set(entry->event, entry);
+   efl_loop_message_handler_message_send
+     (loopsched->loop_data->future_message_handler, entry->event);
+// XXX:
+//   entry->event = ecore_event_add(ECORE_EV_FUTURE_ID, entry,
+//                                  ecore_future_free, entry);
+   efl_event_callback_add((Eo *)entry->event, EFL_LOOP_MESSAGE_EVENT_MESSAGE,
+                          _future_dispatch_cb, entry);
+   efl_event_callback_add((Eo *)entry->event, EFL_EVENT_DEL,
+                          _event_del_cb, entry);
    return &entry->base;
 
   err:
@@ -174,12 +202,17 @@ ecore_future_schedule(Eina_Future_Scheduler *sched, Eina_Future_Scheduler_Cb cb,
 static void
 ecore_future_recall(Eina_Future_Schedule_Entry *s_entry)
 {
+   Eo *msg;
+
    if (shutting_down) return;
    Ecore_Future_Schedule_Entry *entry = (Ecore_Future_Schedule_Entry *)s_entry;
    EINA_SAFETY_ON_NULL_RETURN(entry->event);
-   ecore_event_del(entry->event);
+// XXX:
+//   ecore_event_del(entry->event);
+   msg = entry->event;
    eina_value_flush(&entry->value);
    entry->event = NULL;
+   efl_del(msg);
 }
 
 static Eina_Future_Scheduler ecore_future_scheduler = {
@@ -238,24 +271,28 @@ _ecore_event_init(void)
    //////
    // XXX: ecore future still using legacy...
    shutting_down = EINA_FALSE;
-   ECORE_EV_FUTURE_ID = ecore_event_type_new();
-   future_handler = ecore_event_handler_add(ECORE_EV_FUTURE_ID, ecore_future_dispatched, NULL);
-   EINA_SAFETY_ON_NULL_GOTO(future_handler, err_handler);
+//   ECORE_EV_FUTURE_ID = ecore_event_type_new();
+//   future_handler = ecore_event_handler_add(ECORE_EV_FUTURE_ID, ecore_future_dispatched, NULL);
+//   EINA_SAFETY_ON_NULL_GOTO(future_handler, err_handler);
    //FIXME: Is 512 too high?
-   mp_future_schedule_entry = eina_mempool_add(choice, "Ecore_Future_Event",
-                                               NULL, sizeof(Ecore_Future_Schedule_Entry),
-                                               512);
-   EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool);
+   if (!mp_future_schedule_entry)
+     {
+        mp_future_schedule_entry = eina_mempool_add
+          (choice, "Ecore_Future_Event", NULL,
+           sizeof(Ecore_Future_Schedule_Entry), 512);
+        EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool);
+     }
    //
    //////
 
    return EINA_TRUE;
 
  err_pool:
-   ecore_event_handler_del(future_handler);
-   future_handler = NULL;
- err_handler:
-   ECORE_EV_FUTURE_ID = -1;
+// XXX:
+//   ecore_event_handler_del(future_handler);
+//   future_handler = NULL;
+// err_handler:
+//   ECORE_EV_FUTURE_ID = -1;
    return EINA_FALSE;
 }
 
@@ -266,9 +303,9 @@ _ecore_event_shutdown(void)
 
    //////
    // XXX: ecore future still using legacy...
-   ecore_event_handler_del(future_handler);
-   future_handler = NULL;
-   ECORE_EV_FUTURE_ID = -1;
+//   ecore_event_handler_del(future_handler);
+//   future_handler = NULL;
+//   ECORE_EV_FUTURE_ID = -1;
    //
    //////
 
index b194029..5530c1e 100644 (file)
@@ -84,6 +84,7 @@ typedef struct _Ecore_Factorized_Idle Ecore_Factorized_Idle;
 typedef struct _Efl_Loop_Promise_Simple_Data Efl_Loop_Promise_Simple_Data;
 
 typedef struct _Efl_Loop_Timer_Data Efl_Loop_Timer_Data;
+typedef struct _Efl_Loop_Future_Scheduler Efl_Loop_Future_Scheduler;
 typedef struct _Efl_Loop_Data Efl_Loop_Data;
 
 typedef struct _Message_Handler Message_Handler;
@@ -103,11 +104,22 @@ struct _Message
    Eina_Bool delete_me;
 };
 
+struct _Efl_Loop_Future_Scheduler
+{
+   Eina_Future_Scheduler  eina_future_scheduler;
+   Eo                    *loop;
+   Efl_Loop_Data         *loop_data;
+};
+
 struct _Efl_Loop_Data
 {
    double               loop_time;
    Eina_Hash           *providers;
 
+   Efl_Loop_Future_Scheduler future_scheduler;
+
+   Efl_Loop_Message_Handler *future_message_handler;
+
    Efl_Loop_Timer      *poll_high;
    Efl_Loop_Timer      *poll_medium;
    Efl_Loop_Timer      *poll_low;
index 0ec3592..712bd17 100644 (file)
@@ -460,7 +460,10 @@ _efl_loop_timer_efl_object_parent_set(Eo *obj, Efl_Loop_Timer_Data *pd, Efl_Obje
    _efl_loop_timer_util_loop_clear(pd);
 
    pd->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
-   pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS);
+   if (pd->loop)
+     pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS);
+   else
+     pd->loop_data = NULL;
 
    if (efl_parent_get(obj) != parent) return;
 
index cf58573..5dc1e3f 100644 (file)
@@ -307,6 +307,8 @@ _efl_loop_efl_object_constructor(Eo *obj, Efl_Loop_Data *pd)
    pd->message_handlers = eina_inarray_new(sizeof(Message_Handler), 32);
    pd->epoll_fd = -1;
    pd->timer_fd = -1;
+   pd->future_message_handler = efl_loop_message_handler_get
+     (EFL_LOOP_CLASS, obj, EFL_LOOP_MESSAGE_FUTURE_HANDLER_CLASS);
    return obj;
 }
 
@@ -315,6 +317,8 @@ _efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
 {
    _ecore_main_content_clear(pd);
 
+   pd->future_message_handler = NULL;
+
    eina_hash_free(pd->providers);
    pd->providers = NULL;
 
@@ -325,8 +329,11 @@ _efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
    efl_del(pd->poll_high);
    pd->poll_high = NULL;
 
-   eina_inarray_free(pd->message_handlers);
-   pd->message_handlers = NULL;
+   if (pd->message_handlers)
+     {
+        eina_inarray_free(pd->message_handlers);
+        pd->message_handlers = NULL;
+     }
 
    efl_destructor(efl_super(obj, EFL_LOOP_CLASS));
 
@@ -439,10 +446,10 @@ ecore_loop_promise_unregister(Efl_Loop *l, Efl_Promise *p)
 static Eina_Future *
 _efl_loop_job(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
 {
+   Eina_Future_Scheduler *sched = efl_loop_future_scheduler_get(obj);
    // NOTE: Eolian should do efl_future_then() to bind future to object.
    return efl_future_Eina_FutureXXX_then
-     (obj, eina_future_resolved(efl_loop_future_scheduler_get(obj),
-                                EINA_VALUE_EMPTY));
+     (obj, eina_future_resolved(sched, EINA_VALUE_EMPTY));
 }
 
 EOLIAN static void
@@ -479,6 +486,7 @@ _efl_loop_idle(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
 {
    Efl_Loop_Promise_Simple_Data *d;
    Eina_Promise *p;
+   Eina_Future_Scheduler *sched = efl_loop_future_scheduler_get(obj);
 
    d = efl_loop_promise_simple_data_calloc(1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
@@ -486,8 +494,7 @@ _efl_loop_idle(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
    d->idler = ecore_idler_add(_efl_loop_idle_done, d);
    EINA_SAFETY_ON_NULL_GOTO(d->idler, idler_error);
 
-   p = eina_promise_new(efl_loop_future_scheduler_get(obj),
-                        _efl_loop_idle_cancel, d);
+   p = eina_promise_new(sched, _efl_loop_idle_cancel, d);
    // d is dead if p is NULL
    EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
    d->promise = p;
@@ -504,8 +511,11 @@ static void
 _efl_loop_timeout_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
 {
    Efl_Loop_Promise_Simple_Data *d = data;
-   efl_del(d->timer);
-   d->timer = NULL;
+   if (d->timer)
+     {
+        efl_del(d->timer);
+        d->timer = NULL;
+     }
    efl_loop_promise_simple_data_mp_free(d);
 }
 
@@ -520,11 +530,19 @@ _efl_loop_timeout_done(void *data, const Efl_Event *event)
    efl_del(event->object);
 }
 
+static void
+_efl_loop_timeout_del(void *data, const Efl_Event *event EINA_UNUSED)
+{
+   Efl_Loop_Promise_Simple_Data *d = data;
+   d->timer = NULL;
+}
+
 static Eina_Future *
 _efl_loop_timeout(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, double tim)
 {
    Efl_Loop_Promise_Simple_Data *d;
    Eina_Promise *p;
+   Eina_Future_Scheduler *sched = efl_loop_future_scheduler_get(obj);
 
    d = efl_loop_promise_simple_data_calloc(1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
@@ -533,11 +551,14 @@ _efl_loop_timeout(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, double tim)
                       efl_loop_timer_interval_set(efl_added, tim),
                       efl_event_callback_add(efl_added,
                                              EFL_LOOP_TIMER_EVENT_TICK,
-                                             _efl_loop_timeout_done, d));
+                                             _efl_loop_timeout_done, d),
+                      efl_event_callback_add(efl_added,
+                                             EFL_EVENT_DEL,
+                                             _efl_loop_timeout_del, d)
+                     );
    EINA_SAFETY_ON_NULL_GOTO(d->timer, timer_error);
 
-   p = eina_promise_new(efl_loop_future_scheduler_get(obj),
-                        _efl_loop_timeout_cancel, d);
+   p = eina_promise_new(sched, _efl_loop_timeout_cancel, d);
    // d is dead if p is NULL
    EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
    d->promise = p;
@@ -699,7 +720,20 @@ efl_loop_future_scheduler_get(Eo *obj)
    if (!obj) return NULL;
 
    if (efl_isa(obj, EFL_LOOP_CLASS))
-     return _ecore_event_future_scheduler_get();
+     {
+        Efl_Loop_Data *pd = efl_data_scope_get(obj, EFL_LOOP_CLASS);
+
+        if (!pd) return NULL;
+        if (!pd->future_scheduler.loop)
+          {
+             Eina_Future_Scheduler *sched =
+               _ecore_event_future_scheduler_get();
+             pd->future_scheduler.eina_future_scheduler = *sched;
+             pd->future_scheduler.loop = obj;
+             pd->future_scheduler.loop_data = pd;
+          }
+        return &(pd->future_scheduler.eina_future_scheduler);
+     }
 
    return efl_loop_future_scheduler_get(efl_loop_get(obj));
 }
index 3ef851c..db873cc 100644 (file)
@@ -7,6 +7,9 @@ class Efl.Loop.Message (Efl.Object)
      specific message types.]]
    methods {
    }
+   events {
+      message: Efl.Loop.Message; [[The message payload data]]
+   }
    implements {
       Efl.Object.constructor;
       Efl.Object.destructor;
diff --git a/src/lib/ecore/efl_loop_message_future.c b/src/lib/ecore/efl_loop_message_future.c
new file mode 100644 (file)
index 0000000..6ce4f34
--- /dev/null
@@ -0,0 +1,49 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+
+#include "ecore_private.h"
+
+#define MY_CLASS EFL_LOOP_MESSAGE_FUTURE_CLASS
+
+//////////////////////////////////////////////////////////////////////////
+
+typedef struct _Efl_Loop_Message_Future_Data Efl_Loop_Message_Future_Data;
+
+struct _Efl_Loop_Message_Future_Data
+{
+   void *data;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+EOLIAN static void
+_efl_loop_message_future_data_set(Eo *obj EINA_UNUSED, Efl_Loop_Message_Future_Data *pd, void *data)
+{
+   pd->data = data;
+}
+
+EOLIAN static void *
+_efl_loop_message_future_data_get(Eo *obj EINA_UNUSED, Efl_Loop_Message_Future_Data *pd)
+{
+   return pd->data;
+}
+
+EOLIAN static Efl_Object *
+_efl_loop_message_future_efl_object_constructor(Eo *obj, Efl_Loop_Message_Future_Data *pd EINA_UNUSED)
+{
+   obj = efl_constructor(efl_super(obj, MY_CLASS));
+   return obj;
+}
+
+EOLIAN static void
+_efl_loop_message_future_efl_object_destructor(Eo *obj, Efl_Loop_Message_Future_Data *pd EINA_UNUSED)
+{
+   efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "efl_loop_message_future.eo.c"
diff --git a/src/lib/ecore/efl_loop_message_future.eo b/src/lib/ecore/efl_loop_message_future.eo
new file mode 100644 (file)
index 0000000..8cdc928
--- /dev/null
@@ -0,0 +1,21 @@
+import efl_types;
+import eina_types;
+
+class Efl.Loop.Message.Future (Efl.Loop.Message)
+{
+   [[ Used internally for futures on the loop ]]
+   methods {
+      @property data {
+         [[ ]]
+         set { }
+         get { }
+         values {
+            data: void_ptr; [[ ]]
+         }
+      }
+   }
+   implements {
+      Efl.Object.constructor;
+      Efl.Object.destructor;
+   }
+}
diff --git a/src/lib/ecore/efl_loop_message_future_handler.c b/src/lib/ecore/efl_loop_message_future_handler.c
new file mode 100644 (file)
index 0000000..d45ed1b
--- /dev/null
@@ -0,0 +1,51 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+
+#include "ecore_private.h"
+
+#define MY_CLASS EFL_LOOP_MESSAGE_FUTURE_HANDLER_CLASS
+
+typedef struct _Efl_Loop_Message_Future_Handler_Data Efl_Loop_Message_Future_Handler_Data;
+
+struct _Efl_Loop_Message_Future_Handler_Data
+{
+   void *data; // dummy;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+EOLIAN static Efl_Loop_Message_Future *
+_efl_loop_message_future_handler_message_type_add(Eo *obj, Efl_Loop_Message_Future_Handler_Data *pd)
+{
+   // XXX: implemented event obj cache
+   return efl_add(EFL_LOOP_MESSAGE_FUTURE_CLASS, obj);
+}
+
+EOLIAN static Efl_Object *
+_efl_loop_message_future_handler_efl_object_constructor(Eo *obj, Efl_Loop_Message_Future_Handler_Data *pd EINA_UNUSED)
+{
+   obj = efl_constructor(efl_super(obj, MY_CLASS));
+   return obj;
+}
+
+EOLIAN static void
+_efl_loop_message_future_handler_efl_object_destructor(Eo *obj, Efl_Loop_Message_Future_Handler_Data *pd EINA_UNUSED)
+{
+   efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_efl_loop_message_future_handler_efl_loop_message_handler_message_call(Eo *obj, Efl_Loop_Message_Future_Handler_Data *pd EINA_UNUSED, Efl_Loop_Message *message)
+{
+   efl_event_callback_call
+     (obj, EFL_LOOP_MESSAGE_FUTURE_HANDLER_EVENT_MESSAGE_FUTURE, message);
+   efl_loop_message_handler_message_call
+     (efl_super(obj, MY_CLASS), message);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "efl_loop_message_future_handler.eo.c"
diff --git a/src/lib/ecore/efl_loop_message_future_handler.eo b/src/lib/ecore/efl_loop_message_future_handler.eo
new file mode 100644 (file)
index 0000000..e53c054
--- /dev/null
@@ -0,0 +1,21 @@
+import efl_types;
+import eina_types;
+
+class Efl.Loop.Message.Future.Handler (Efl.Loop.Message.Handler)
+{
+   [[ Internal use for future on an efl loop - replacing legacy ecore events ]]
+   methods {
+      message_type_add {
+         [[ ]]
+         return: Efl.Loop.Message.Future; [[ ]]
+      }
+   }
+   events {
+      message,future: Efl.Loop.Message.Future; [[ ]]
+   }
+   implements {
+      Efl.Object.constructor;
+      Efl.Object.destructor;
+      Efl.Loop.Message.Handler.message_call; [[ ]]
+   }
+}
index 04862da..05ecdbc 100644 (file)
@@ -90,6 +90,8 @@ _efl_loop_message_handler_message_call(Eo *obj, Efl_Loop_Message_Handler_Data *p
           msg->delete_me = EINA_TRUE;
         break;
      }
+   efl_event_callback_call(message, EFL_LOOP_MESSAGE_EVENT_MESSAGE,
+                           message);
    efl_event_callback_call(obj, EFL_LOOP_MESSAGE_HANDLER_EVENT_MESSAGE,
                            message);
    // XXX: implement message object cache...
index 437a9cf..fbb8784 100644 (file)
@@ -3,6 +3,7 @@
 #endif
 
 #include "eina_private.h"
+#include "eina_lock.h"
 #include "eina_promise.h"
 #include "eina_mempool.h"
 #include "eina_promise_private.h"
@@ -117,6 +118,7 @@ struct _Eina_Future {
 
 static Eina_Mempool *_promise_mp = NULL;
 static Eina_Mempool *_future_mp = NULL;
+static Eina_Lock _pending_futures_lock;
 static Eina_List *_pending_futures = NULL;
 static int _promise_log_dom = -1;
 
@@ -407,7 +409,9 @@ _eina_future_dispatch(Eina_Future *f, Eina_Value value)
 static void
 _scheduled_entry_cb(Eina_Future *f, Eina_Value value)
 {
+   eina_lock_take(&_pending_futures_lock);
    _pending_futures = eina_list_remove(_pending_futures, f);
+   eina_lock_release(&_pending_futures_lock);
    f->scheduled_entry = NULL;
    _eina_future_dispatch(f, value);
 }
@@ -436,7 +440,9 @@ _eina_future_cancel(Eina_Future *f, int err)
      {
         eina_future_schedule_entry_recall(f->scheduled_entry);
         f->scheduled_entry = NULL;
+        eina_lock_take(&_pending_futures_lock);
         _pending_futures = eina_list_remove(_pending_futures, f);
+        eina_lock_release(&_pending_futures_lock);
      }
 
    if (f->promise)
@@ -470,7 +476,9 @@ _eina_future_schedule(Eina_Promise *p,
                                                f, value);
    EINA_SAFETY_ON_NULL_GOTO(f->scheduled_entry, err);
    assert(f->scheduled_entry->scheduler != NULL);
+   eina_lock_take(&_pending_futures_lock);
    _pending_futures = eina_list_append(_pending_futures, f);
+   eina_lock_release(&_pending_futures_lock);
    DBG("The promise %p schedule the future %p with cb: %p and data: %p",
        p, f, f->cb, f->data);
    return;
@@ -523,6 +531,8 @@ eina_promise_init(void)
                                  NULL, sizeof(Eina_Future), 512);
    EINA_SAFETY_ON_NULL_GOTO(_future_mp, err_future);
 
+   eina_lock_recursive_new(&_pending_futures_lock);
+
    return EINA_TRUE;
 
  err_future:
@@ -537,14 +547,17 @@ eina_promise_init(void)
 EAPI void
 __eina_promise_cancel_all(void)
 {
+   eina_lock_take(&_pending_futures_lock);
    while (_pending_futures)
      _eina_future_cancel(_pending_futures->data, ECANCELED);
+   eina_lock_release(&_pending_futures_lock);
 }
 
 Eina_Bool
 eina_promise_shutdown(void)
 {
    __eina_promise_cancel_all();
+   eina_lock_free(&_pending_futures_lock);
    eina_mempool_del(_future_mp);
    eina_mempool_del(_promise_mp);
    eina_log_domain_unregister(_promise_log_dom);