aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-12-28 01:19:52 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-12-28 02:24:12 +0900
commitb27ca559f6fd63dac36ae74bcfc8132ea19299a5 (patch)
tree9fdf2554c96029d9aa0c428e8f7d6ea3e5d12d16
parentEfl_Ui.h - remember to define EWAPI too (diff)
downloadefl-b27ca559f6fd63dac36ae74bcfc8132ea19299a5.tar.gz
remove elgacy ecore event usage in futures that limit to mainloop only
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.
-rw-r--r--src/Makefile_Ecore.am4
-rw-r--r--src/lib/ecore/Ecore_Eo.h3
-rw-r--r--src/lib/ecore/ecore_events.c105
-rw-r--r--src/lib/ecore/ecore_private.h12
-rw-r--r--src/lib/ecore/ecore_timer.c5
-rw-r--r--src/lib/ecore/efl_loop.c58
-rw-r--r--src/lib/ecore/efl_loop_message.eo3
-rw-r--r--src/lib/ecore/efl_loop_message_future.c49
-rw-r--r--src/lib/ecore/efl_loop_message_future.eo21
-rw-r--r--src/lib/ecore/efl_loop_message_future_handler.c51
-rw-r--r--src/lib/ecore/efl_loop_message_future_handler.eo21
-rw-r--r--src/lib/ecore/efl_loop_message_handler.c2
-rw-r--r--src/lib/eina/eina_promise.c13
13 files changed, 300 insertions, 47 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index d0680de060..b9553079fc 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -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 \
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index be1929aa42..bc8174196e 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -32,6 +32,9 @@
#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
*
diff --git a/src/lib/ecore/ecore_events.c b/src/lib/ecore/ecore_events.c
index 3adbe042ea..3911abeb67 100644
--- a/src/lib/ecore/ecore_events.c
+++ b/src/lib/ecore/ecore_events.c
@@ -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;
//
//////
diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h
index d1046f0fb5..252e697e2a 100644
--- a/src/lib/ecore/ecore_private.h
+++ b/src/lib/ecore/ecore_private.h
@@ -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;
diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c
index 0ec3592643..712bd17a85 100644
--- a/src/lib/ecore/ecore_timer.c
+++ b/src/lib/ecore/ecore_timer.c
@@ -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;
diff --git a/src/lib/ecore/efl_loop.c b/src/lib/ecore/efl_loop.c
index cf58573d28..5dc1e3fdec 100644
--- a/src/lib/ecore/efl_loop.c
+++ b/src/lib/ecore/efl_loop.c
@@ -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));
}
diff --git a/src/lib/ecore/efl_loop_message.eo b/src/lib/ecore/efl_loop_message.eo
index 3ef851c55e..db873cc46d 100644
--- a/src/lib/ecore/efl_loop_message.eo
+++ b/src/lib/ecore/efl_loop_message.eo
@@ -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
index 0000000000..6ce4f3455a
--- /dev/null
+++ b/src/lib/ecore/efl_loop_message_future.c
@@ -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
index 0000000000..8cdc928ab2
--- /dev/null
+++ b/src/lib/ecore/efl_loop_message_future.eo
@@ -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
index 0000000000..d45ed1be9a
--- /dev/null
+++ b/src/lib/ecore/efl_loop_message_future_handler.c
@@ -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
index 0000000000..e53c054665
--- /dev/null
+++ b/src/lib/ecore/efl_loop_message_future_handler.eo
@@ -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; [[ ]]
+ }
+}
diff --git a/src/lib/ecore/efl_loop_message_handler.c b/src/lib/ecore/efl_loop_message_handler.c
index 04862da756..05ecdbcab2 100644
--- a/src/lib/ecore/efl_loop_message_handler.c
+++ b/src/lib/ecore/efl_loop_message_handler.c
@@ -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...
diff --git a/src/lib/eina/eina_promise.c b/src/lib/eina/eina_promise.c
index 437a9cf431..fbb878447d 100644
--- a/src/lib/eina/eina_promise.c
+++ b/src/lib/eina/eina_promise.c
@@ -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);