summaryrefslogtreecommitdiff
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
parent6ccfea3d51c9571e4cc40d6f1d0c0a4e2bf07bd4 (diff)
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 = \
38 38
39ecore_eolian_files = \ 39ecore_eolian_files = \
40 $(ecore_eolian_files_public) \ 40 $(ecore_eolian_files_public) \
41 lib/ecore/efl_loop_message_future_handler.eo \
42 lib/ecore/efl_loop_message_future.eo \
41 lib/ecore/efl_promise.eo \ 43 lib/ecore/efl_promise.eo \
42 lib/ecore/efl_model_item.eo \ 44 lib/ecore/efl_model_item.eo \
43 lib/ecore/efl_model_container.eo \ 45 lib/ecore/efl_model_container.eo \
@@ -97,6 +99,8 @@ lib/ecore/efl_loop_fd.c \
97lib/ecore/efl_loop_handler.c \ 99lib/ecore/efl_loop_handler.c \
98lib/ecore/efl_loop_message.c \ 100lib/ecore/efl_loop_message.c \
99lib/ecore/efl_loop_message_handler.c \ 101lib/ecore/efl_loop_message_handler.c \
102lib/ecore/efl_loop_message_future.c \
103lib/ecore/efl_loop_message_future_handler.c \
100lib/ecore/efl_io_closer_fd.c \ 104lib/ecore/efl_io_closer_fd.c \
101lib/ecore/efl_io_positioner_fd.c \ 105lib/ecore/efl_io_positioner_fd.c \
102lib/ecore/efl_io_reader_fd.c \ 106lib/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 @@
32#include "ecore_event_message.eo.h" 32#include "ecore_event_message.eo.h"
33#include "ecore_event_message_handler.eo.h" 33#include "ecore_event_message_handler.eo.h"
34 34
35#include "efl_loop_message_future.eo.h"
36#include "efl_loop_message_future_handler.eo.h"
37
35/** 38/**
36 * @ingroup Ecore_MainLoop_Group 39 * @ingroup Ecore_MainLoop_Group
37 * 40 *
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
12 Eina_Future_Schedule_Entry base; 12 Eina_Future_Schedule_Entry base;
13 Eina_Future_Scheduler_Cb cb; 13 Eina_Future_Scheduler_Cb cb;
14 Eina_Future *future; 14 Eina_Future *future;
15 Ecore_Event *event; 15 Eo *event;
16 Eina_Value value; 16 Eina_Value value;
17} Ecore_Future_Schedule_Entry; 17} Ecore_Future_Schedule_Entry;
18 18
19////// 19//////
20// XXX: still using legacy ecore events 20// XXX: still using legacy ecore events
21static Ecore_Event_Handler *future_handler = NULL; 21//static Ecore_Event_Handler *future_handler = NULL;
22static Eina_Bool shutting_down = EINA_FALSE; 22static Eina_Bool shutting_down = EINA_FALSE;
23static Eina_Mempool *mp_future_schedule_entry = NULL; 23static Eina_Mempool *mp_future_schedule_entry = NULL;
24static int ECORE_EV_FUTURE_ID = -1; 24//static int ECORE_EV_FUTURE_ID = -1;
25// 25//
26////// 26//////
27 27
@@ -71,17 +71,6 @@ ecore_event_add(int type,
71 return (Ecore_Event *)msg; 71 return (Ecore_Event *)msg;
72} 72}
73 73
74static void
75_event_del_cb(void *data, const Efl_Event *ev)
76{
77 Ecore_Future_Schedule_Entry *entry = data;
78 if ((ev->object == (Eo *) entry->event) && entry->future)
79 {
80 eina_future_cancel(entry->future);
81 eina_value_flush(&entry->value);
82 }
83}
84
85EAPI void * 74EAPI void *
86ecore_event_del(Ecore_Event *event) 75ecore_event_del(Ecore_Event *event)
87{ 76{
@@ -127,8 +116,11 @@ ecore_event_current_event_get(void)
127 return ecore_event_message_handler_current_event_get(_event_msg_handler); 116 return ecore_event_message_handler_current_event_get(_event_msg_handler);
128} 117}
129 118
119/* XXX:
130static Eina_Bool 120static Eina_Bool
131ecore_future_dispatched(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) 121ecore_future_dispatched(void *data EINA_UNUSED,
122 int type EINA_UNUSED,
123 void *event)
132{ 124{
133 Ecore_Future_Schedule_Entry *entry = event; 125 Ecore_Future_Schedule_Entry *entry = event;
134 EINA_SAFETY_ON_NULL_RETURN_VAL(entry, EINA_FALSE); 126 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
139} 131}
140 132
141static void 133static void
142ecore_future_free(void *user_data, void *func_data EINA_UNUSED) 134ecore_future_free(void *user_data,
135 void *func_data EINA_UNUSED)
143{ 136{
144 Ecore_Future_Schedule_Entry *entry = user_data; 137 Ecore_Future_Schedule_Entry *entry = user_data;
145 if (entry->event) 138 if (entry->event)
@@ -149,10 +142,35 @@ ecore_future_free(void *user_data, void *func_data EINA_UNUSED)
149 } 142 }
150 eina_mempool_free(mp_future_schedule_entry, entry); 143 eina_mempool_free(mp_future_schedule_entry, entry);
151} 144}
145*/
146
147static void
148_future_dispatch_cb(void *data, const Efl_Event *ev EINA_UNUSED)
149{
150 Ecore_Future_Schedule_Entry *entry = data;
151 entry->event = NULL;
152 entry->cb(entry->future, entry->value);
153}
154
155static void
156_event_del_cb(void *data, const Efl_Event *ev)
157{
158 Ecore_Future_Schedule_Entry *entry = data;
159 if ((ev->object == (Eo *) entry->event) && entry->future)
160 {
161 eina_future_cancel(entry->future);
162 eina_value_flush(&entry->value);
163 }
164 eina_mempool_free(mp_future_schedule_entry, entry);
165}
152 166
153static Eina_Future_Schedule_Entry * 167static Eina_Future_Schedule_Entry *
154ecore_future_schedule(Eina_Future_Scheduler *sched, Eina_Future_Scheduler_Cb cb, Eina_Future *future, Eina_Value value) 168ecore_future_schedule(Eina_Future_Scheduler *sched,
169 Eina_Future_Scheduler_Cb cb,
170 Eina_Future *future,
171 Eina_Value value)
155{ 172{
173 Efl_Loop_Future_Scheduler *loopsched = (Efl_Loop_Future_Scheduler *)sched;
156 Ecore_Future_Schedule_Entry *entry; 174 Ecore_Future_Schedule_Entry *entry;
157 175
158 entry = eina_mempool_malloc(mp_future_schedule_entry, sizeof(*entry)); 176 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,
161 entry->cb = cb; 179 entry->cb = cb;
162 entry->future = future; 180 entry->future = future;
163 entry->value = value; 181 entry->value = value;
164 entry->event = ecore_event_add(ECORE_EV_FUTURE_ID, entry, ecore_future_free, entry); 182 entry->event = efl_loop_message_future_handler_message_type_add
183 (loopsched->loop_data->future_message_handler);
165 EINA_SAFETY_ON_NULL_GOTO(entry->event, err); 184 EINA_SAFETY_ON_NULL_GOTO(entry->event, err);
166 efl_event_callback_add((Eo *) entry->event, EFL_EVENT_DEL, _event_del_cb, entry); 185 efl_loop_message_future_data_set(entry->event, entry);
186 efl_loop_message_handler_message_send
187 (loopsched->loop_data->future_message_handler, entry->event);
188// XXX:
189// entry->event = ecore_event_add(ECORE_EV_FUTURE_ID, entry,
190// ecore_future_free, entry);
191 efl_event_callback_add((Eo *)entry->event, EFL_LOOP_MESSAGE_EVENT_MESSAGE,
192 _future_dispatch_cb, entry);
193 efl_event_callback_add((Eo *)entry->event, EFL_EVENT_DEL,
194 _event_del_cb, entry);
167 return &entry->base; 195 return &entry->base;
168 196
169 err: 197 err:
@@ -174,12 +202,17 @@ ecore_future_schedule(Eina_Future_Scheduler *sched, Eina_Future_Scheduler_Cb cb,
174static void 202static void
175ecore_future_recall(Eina_Future_Schedule_Entry *s_entry) 203ecore_future_recall(Eina_Future_Schedule_Entry *s_entry)
176{ 204{
205 Eo *msg;
206
177 if (shutting_down) return; 207 if (shutting_down) return;
178 Ecore_Future_Schedule_Entry *entry = (Ecore_Future_Schedule_Entry *)s_entry; 208 Ecore_Future_Schedule_Entry *entry = (Ecore_Future_Schedule_Entry *)s_entry;
179 EINA_SAFETY_ON_NULL_RETURN(entry->event); 209 EINA_SAFETY_ON_NULL_RETURN(entry->event);
180 ecore_event_del(entry->event); 210// XXX:
211// ecore_event_del(entry->event);
212 msg = entry->event;
181 eina_value_flush(&entry->value); 213 eina_value_flush(&entry->value);
182 entry->event = NULL; 214 entry->event = NULL;
215 efl_del(msg);
183} 216}
184 217
185static Eina_Future_Scheduler ecore_future_scheduler = { 218static Eina_Future_Scheduler ecore_future_scheduler = {
@@ -238,24 +271,28 @@ _ecore_event_init(void)
238 ////// 271 //////
239 // XXX: ecore future still using legacy... 272 // XXX: ecore future still using legacy...
240 shutting_down = EINA_FALSE; 273 shutting_down = EINA_FALSE;
241 ECORE_EV_FUTURE_ID = ecore_event_type_new(); 274// ECORE_EV_FUTURE_ID = ecore_event_type_new();
242 future_handler = ecore_event_handler_add(ECORE_EV_FUTURE_ID, ecore_future_dispatched, NULL); 275// future_handler = ecore_event_handler_add(ECORE_EV_FUTURE_ID, ecore_future_dispatched, NULL);
243 EINA_SAFETY_ON_NULL_GOTO(future_handler, err_handler); 276// EINA_SAFETY_ON_NULL_GOTO(future_handler, err_handler);
244 //FIXME: Is 512 too high? 277 //FIXME: Is 512 too high?
245 mp_future_schedule_entry = eina_mempool_add(choice, "Ecore_Future_Event", 278 if (!mp_future_schedule_entry)
246 NULL, sizeof(Ecore_Future_Schedule_Entry), 279 {
247 512); 280 mp_future_schedule_entry = eina_mempool_add
248 EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool); 281 (choice, "Ecore_Future_Event", NULL,
282 sizeof(Ecore_Future_Schedule_Entry), 512);
283 EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool);
284 }
249 // 285 //
250 ////// 286 //////
251 287
252 return EINA_TRUE; 288 return EINA_TRUE;
253 289
254 err_pool: 290 err_pool:
255 ecore_event_handler_del(future_handler); 291// XXX:
256 future_handler = NULL; 292// ecore_event_handler_del(future_handler);
257 err_handler: 293// future_handler = NULL;
258 ECORE_EV_FUTURE_ID = -1; 294// err_handler:
295// ECORE_EV_FUTURE_ID = -1;
259 return EINA_FALSE; 296 return EINA_FALSE;
260} 297}
261 298
@@ -266,9 +303,9 @@ _ecore_event_shutdown(void)
266 303
267 ////// 304 //////
268 // XXX: ecore future still using legacy... 305 // XXX: ecore future still using legacy...
269 ecore_event_handler_del(future_handler); 306// ecore_event_handler_del(future_handler);
270 future_handler = NULL; 307// future_handler = NULL;
271 ECORE_EV_FUTURE_ID = -1; 308// ECORE_EV_FUTURE_ID = -1;
272 // 309 //
273 ////// 310 //////
274 311
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;
84typedef struct _Efl_Loop_Promise_Simple_Data Efl_Loop_Promise_Simple_Data; 84typedef struct _Efl_Loop_Promise_Simple_Data Efl_Loop_Promise_Simple_Data;
85 85
86typedef struct _Efl_Loop_Timer_Data Efl_Loop_Timer_Data; 86typedef struct _Efl_Loop_Timer_Data Efl_Loop_Timer_Data;
87typedef struct _Efl_Loop_Future_Scheduler Efl_Loop_Future_Scheduler;
87typedef struct _Efl_Loop_Data Efl_Loop_Data; 88typedef struct _Efl_Loop_Data Efl_Loop_Data;
88 89
89typedef struct _Message_Handler Message_Handler; 90typedef struct _Message_Handler Message_Handler;
@@ -103,11 +104,22 @@ struct _Message
103 Eina_Bool delete_me; 104 Eina_Bool delete_me;
104}; 105};
105 106
107struct _Efl_Loop_Future_Scheduler
108{
109 Eina_Future_Scheduler eina_future_scheduler;
110 Eo *loop;
111 Efl_Loop_Data *loop_data;
112};
113
106struct _Efl_Loop_Data 114struct _Efl_Loop_Data
107{ 115{
108 double loop_time; 116 double loop_time;
109 Eina_Hash *providers; 117 Eina_Hash *providers;
110 118
119 Efl_Loop_Future_Scheduler future_scheduler;
120
121 Efl_Loop_Message_Handler *future_message_handler;
122
111 Efl_Loop_Timer *poll_high; 123 Efl_Loop_Timer *poll_high;
112 Efl_Loop_Timer *poll_medium; 124 Efl_Loop_Timer *poll_medium;
113 Efl_Loop_Timer *poll_low; 125 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
460 _efl_loop_timer_util_loop_clear(pd); 460 _efl_loop_timer_util_loop_clear(pd);
461 461
462 pd->loop = efl_provider_find(obj, EFL_LOOP_CLASS); 462 pd->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
463 pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS); 463 if (pd->loop)
464 pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS);
465 else
466 pd->loop_data = NULL;
464 467
465 if (efl_parent_get(obj) != parent) return; 468 if (efl_parent_get(obj) != parent) return;
466 469
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)
307 pd->message_handlers = eina_inarray_new(sizeof(Message_Handler), 32); 307 pd->message_handlers = eina_inarray_new(sizeof(Message_Handler), 32);
308 pd->epoll_fd = -1; 308 pd->epoll_fd = -1;
309 pd->timer_fd = -1; 309 pd->timer_fd = -1;
310 pd->future_message_handler = efl_loop_message_handler_get
311 (EFL_LOOP_CLASS, obj, EFL_LOOP_MESSAGE_FUTURE_HANDLER_CLASS);
310 return obj; 312 return obj;
311} 313}
312 314
@@ -315,6 +317,8 @@ _efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
315{ 317{
316 _ecore_main_content_clear(pd); 318 _ecore_main_content_clear(pd);
317 319
320 pd->future_message_handler = NULL;
321
318 eina_hash_free(pd->providers); 322 eina_hash_free(pd->providers);
319 pd->providers = NULL; 323 pd->providers = NULL;
320 324
@@ -325,8 +329,11 @@ _efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
325 efl_del(pd->poll_high); 329 efl_del(pd->poll_high);
326 pd->poll_high = NULL; 330 pd->poll_high = NULL;
327 331
328 eina_inarray_free(pd->message_handlers); 332 if (pd->message_handlers)
329 pd->message_handlers = NULL; 333 {
334 eina_inarray_free(pd->message_handlers);
335 pd->message_handlers = NULL;
336 }
330 337
331 efl_destructor(efl_super(obj, EFL_LOOP_CLASS)); 338 efl_destructor(efl_super(obj, EFL_LOOP_CLASS));
332 339
@@ -439,10 +446,10 @@ ecore_loop_promise_unregister(Efl_Loop *l, Efl_Promise *p)
439static Eina_Future * 446static Eina_Future *
440_efl_loop_job(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED) 447_efl_loop_job(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
441{ 448{
449 Eina_Future_Scheduler *sched = efl_loop_future_scheduler_get(obj);
442 // NOTE: Eolian should do efl_future_then() to bind future to object. 450 // NOTE: Eolian should do efl_future_then() to bind future to object.
443 return efl_future_Eina_FutureXXX_then 451 return efl_future_Eina_FutureXXX_then
444 (obj, eina_future_resolved(efl_loop_future_scheduler_get(obj), 452 (obj, eina_future_resolved(sched, EINA_VALUE_EMPTY));
445 EINA_VALUE_EMPTY));
446} 453}
447 454
448EOLIAN static void 455EOLIAN static void
@@ -479,6 +486,7 @@ _efl_loop_idle(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
479{ 486{
480 Efl_Loop_Promise_Simple_Data *d; 487 Efl_Loop_Promise_Simple_Data *d;
481 Eina_Promise *p; 488 Eina_Promise *p;
489 Eina_Future_Scheduler *sched = efl_loop_future_scheduler_get(obj);
482 490
483 d = efl_loop_promise_simple_data_calloc(1); 491 d = efl_loop_promise_simple_data_calloc(1);
484 EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL); 492 EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
@@ -486,8 +494,7 @@ _efl_loop_idle(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
486 d->idler = ecore_idler_add(_efl_loop_idle_done, d); 494 d->idler = ecore_idler_add(_efl_loop_idle_done, d);
487 EINA_SAFETY_ON_NULL_GOTO(d->idler, idler_error); 495 EINA_SAFETY_ON_NULL_GOTO(d->idler, idler_error);
488 496
489 p = eina_promise_new(efl_loop_future_scheduler_get(obj), 497 p = eina_promise_new(sched, _efl_loop_idle_cancel, d);
490 _efl_loop_idle_cancel, d);
491 // d is dead if p is NULL 498 // d is dead if p is NULL
492 EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL); 499 EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
493 d->promise = p; 500 d->promise = p;
@@ -504,8 +511,11 @@ static void
504_efl_loop_timeout_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED) 511_efl_loop_timeout_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
505{ 512{
506 Efl_Loop_Promise_Simple_Data *d = data; 513 Efl_Loop_Promise_Simple_Data *d = data;
507 efl_del(d->timer); 514 if (d->timer)
508 d->timer = NULL; 515 {
516 efl_del(d->timer);
517 d->timer = NULL;
518 }
509 efl_loop_promise_simple_data_mp_free(d); 519 efl_loop_promise_simple_data_mp_free(d);
510} 520}
511 521
@@ -520,11 +530,19 @@ _efl_loop_timeout_done(void *data, const Efl_Event *event)
520 efl_del(event->object); 530 efl_del(event->object);
521} 531}
522 532
533static void
534_efl_loop_timeout_del(void *data, const Efl_Event *event EINA_UNUSED)
535{
536 Efl_Loop_Promise_Simple_Data *d = data;
537 d->timer = NULL;
538}
539
523static Eina_Future * 540static Eina_Future *
524_efl_loop_timeout(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, double tim) 541_efl_loop_timeout(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, double tim)
525{ 542{
526 Efl_Loop_Promise_Simple_Data *d; 543 Efl_Loop_Promise_Simple_Data *d;
527 Eina_Promise *p; 544 Eina_Promise *p;
545 Eina_Future_Scheduler *sched = efl_loop_future_scheduler_get(obj);
528 546
529 d = efl_loop_promise_simple_data_calloc(1); 547 d = efl_loop_promise_simple_data_calloc(1);
530 EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL); 548 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)
533 efl_loop_timer_interval_set(efl_added, tim), 551 efl_loop_timer_interval_set(efl_added, tim),
534 efl_event_callback_add(efl_added, 552 efl_event_callback_add(efl_added,
535 EFL_LOOP_TIMER_EVENT_TICK, 553 EFL_LOOP_TIMER_EVENT_TICK,
536 _efl_loop_timeout_done, d)); 554 _efl_loop_timeout_done, d),
555 efl_event_callback_add(efl_added,
556 EFL_EVENT_DEL,
557 _efl_loop_timeout_del, d)
558 );
537 EINA_SAFETY_ON_NULL_GOTO(d->timer, timer_error); 559 EINA_SAFETY_ON_NULL_GOTO(d->timer, timer_error);
538 560
539 p = eina_promise_new(efl_loop_future_scheduler_get(obj), 561 p = eina_promise_new(sched, _efl_loop_timeout_cancel, d);
540 _efl_loop_timeout_cancel, d);
541 // d is dead if p is NULL 562 // d is dead if p is NULL
542 EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL); 563 EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
543 d->promise = p; 564 d->promise = p;
@@ -699,7 +720,20 @@ efl_loop_future_scheduler_get(Eo *obj)
699 if (!obj) return NULL; 720 if (!obj) return NULL;
700 721
701 if (efl_isa(obj, EFL_LOOP_CLASS)) 722 if (efl_isa(obj, EFL_LOOP_CLASS))
702 return _ecore_event_future_scheduler_get(); 723 {
724 Efl_Loop_Data *pd = efl_data_scope_get(obj, EFL_LOOP_CLASS);
725
726 if (!pd) return NULL;
727 if (!pd->future_scheduler.loop)
728 {
729 Eina_Future_Scheduler *sched =
730 _ecore_event_future_scheduler_get();
731 pd->future_scheduler.eina_future_scheduler = *sched;
732 pd->future_scheduler.loop = obj;
733 pd->future_scheduler.loop_data = pd;
734 }
735 return &(pd->future_scheduler.eina_future_scheduler);
736 }
703 737
704 return efl_loop_future_scheduler_get(efl_loop_get(obj)); 738 return efl_loop_future_scheduler_get(efl_loop_get(obj));
705} 739}
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)
7 specific message types.]] 7 specific message types.]]
8 methods { 8 methods {
9 } 9 }
10 events {
11 message: Efl.Loop.Message; [[The message payload data]]
12 }
10 implements { 13 implements {
11 Efl.Object.constructor; 14 Efl.Object.constructor;
12 Efl.Object.destructor; 15 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 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Ecore.h>
6
7#include "ecore_private.h"
8
9#define MY_CLASS EFL_LOOP_MESSAGE_FUTURE_CLASS
10
11//////////////////////////////////////////////////////////////////////////
12
13typedef struct _Efl_Loop_Message_Future_Data Efl_Loop_Message_Future_Data;
14
15struct _Efl_Loop_Message_Future_Data
16{
17 void *data;
18};
19
20//////////////////////////////////////////////////////////////////////////
21
22EOLIAN static void
23_efl_loop_message_future_data_set(Eo *obj EINA_UNUSED, Efl_Loop_Message_Future_Data *pd, void *data)
24{
25 pd->data = data;
26}
27
28EOLIAN static void *
29_efl_loop_message_future_data_get(Eo *obj EINA_UNUSED, Efl_Loop_Message_Future_Data *pd)
30{
31 return pd->data;
32}
33
34EOLIAN static Efl_Object *
35_efl_loop_message_future_efl_object_constructor(Eo *obj, Efl_Loop_Message_Future_Data *pd EINA_UNUSED)
36{
37 obj = efl_constructor(efl_super(obj, MY_CLASS));
38 return obj;
39}
40
41EOLIAN static void
42_efl_loop_message_future_efl_object_destructor(Eo *obj, Efl_Loop_Message_Future_Data *pd EINA_UNUSED)
43{
44 efl_destructor(efl_super(obj, MY_CLASS));
45}
46
47//////////////////////////////////////////////////////////////////////////
48
49#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 @@
1import efl_types;
2import eina_types;
3
4class Efl.Loop.Message.Future (Efl.Loop.Message)
5{
6 [[ Used internally for futures on the loop ]]
7 methods {
8 @property data {
9 [[ ]]
10 set { }
11 get { }
12 values {
13 data: void_ptr; [[ ]]
14 }
15 }
16 }
17 implements {
18 Efl.Object.constructor;
19 Efl.Object.destructor;
20 }
21}
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 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Ecore.h>
6
7#include "ecore_private.h"
8
9#define MY_CLASS EFL_LOOP_MESSAGE_FUTURE_HANDLER_CLASS
10
11typedef struct _Efl_Loop_Message_Future_Handler_Data Efl_Loop_Message_Future_Handler_Data;
12
13struct _Efl_Loop_Message_Future_Handler_Data
14{
15 void *data; // dummy;
16};
17
18//////////////////////////////////////////////////////////////////////////
19
20EOLIAN static Efl_Loop_Message_Future *
21_efl_loop_message_future_handler_message_type_add(Eo *obj, Efl_Loop_Message_Future_Handler_Data *pd)
22{
23 // XXX: implemented event obj cache
24 return efl_add(EFL_LOOP_MESSAGE_FUTURE_CLASS, obj);
25}
26
27EOLIAN static Efl_Object *
28_efl_loop_message_future_handler_efl_object_constructor(Eo *obj, Efl_Loop_Message_Future_Handler_Data *pd EINA_UNUSED)
29{
30 obj = efl_constructor(efl_super(obj, MY_CLASS));
31 return obj;
32}
33
34EOLIAN static void
35_efl_loop_message_future_handler_efl_object_destructor(Eo *obj, Efl_Loop_Message_Future_Handler_Data *pd EINA_UNUSED)
36{
37 efl_destructor(efl_super(obj, MY_CLASS));
38}
39
40EOLIAN static void
41_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)
42{
43 efl_event_callback_call
44 (obj, EFL_LOOP_MESSAGE_FUTURE_HANDLER_EVENT_MESSAGE_FUTURE, message);
45 efl_loop_message_handler_message_call
46 (efl_super(obj, MY_CLASS), message);
47}
48
49//////////////////////////////////////////////////////////////////////////
50
51#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 @@
1import efl_types;
2import eina_types;
3
4class Efl.Loop.Message.Future.Handler (Efl.Loop.Message.Handler)
5{
6 [[ Internal use for future on an efl loop - replacing legacy ecore events ]]
7 methods {
8 message_type_add {
9 [[ ]]
10 return: Efl.Loop.Message.Future; [[ ]]
11 }
12 }
13 events {
14 message,future: Efl.Loop.Message.Future; [[ ]]
15 }
16 implements {
17 Efl.Object.constructor;
18 Efl.Object.destructor;
19 Efl.Loop.Message.Handler.message_call; [[ ]]
20 }
21}
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
90 msg->delete_me = EINA_TRUE; 90 msg->delete_me = EINA_TRUE;
91 break; 91 break;
92 } 92 }
93 efl_event_callback_call(message, EFL_LOOP_MESSAGE_EVENT_MESSAGE,
94 message);
93 efl_event_callback_call(obj, EFL_LOOP_MESSAGE_HANDLER_EVENT_MESSAGE, 95 efl_event_callback_call(obj, EFL_LOOP_MESSAGE_HANDLER_EVENT_MESSAGE,
94 message); 96 message);
95 // XXX: implement message object cache... 97 // 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 @@
3#endif 3#endif
4 4
5#include "eina_private.h" 5#include "eina_private.h"
6#include "eina_lock.h"
6#include "eina_promise.h" 7#include "eina_promise.h"
7#include "eina_mempool.h" 8#include "eina_mempool.h"
8#include "eina_promise_private.h" 9#include "eina_promise_private.h"
@@ -117,6 +118,7 @@ struct _Eina_Future {
117 118
118static Eina_Mempool *_promise_mp = NULL; 119static Eina_Mempool *_promise_mp = NULL;
119static Eina_Mempool *_future_mp = NULL; 120static Eina_Mempool *_future_mp = NULL;
121static Eina_Lock _pending_futures_lock;
120static Eina_List *_pending_futures = NULL; 122static Eina_List *_pending_futures = NULL;
121static int _promise_log_dom = -1; 123static int _promise_log_dom = -1;
122 124
@@ -407,7 +409,9 @@ _eina_future_dispatch(Eina_Future *f, Eina_Value value)
407static void 409static void
408_scheduled_entry_cb(Eina_Future *f, Eina_Value value) 410_scheduled_entry_cb(Eina_Future *f, Eina_Value value)
409{ 411{
412 eina_lock_take(&_pending_futures_lock);
410 _pending_futures = eina_list_remove(_pending_futures, f); 413 _pending_futures = eina_list_remove(_pending_futures, f);
414 eina_lock_release(&_pending_futures_lock);
411 f->scheduled_entry = NULL; 415 f->scheduled_entry = NULL;
412 _eina_future_dispatch(f, value); 416 _eina_future_dispatch(f, value);
413} 417}
@@ -436,7 +440,9 @@ _eina_future_cancel(Eina_Future *f, int err)
436 { 440 {
437 eina_future_schedule_entry_recall(f->scheduled_entry); 441 eina_future_schedule_entry_recall(f->scheduled_entry);
438 f->scheduled_entry = NULL; 442 f->scheduled_entry = NULL;
443 eina_lock_take(&_pending_futures_lock);
439 _pending_futures = eina_list_remove(_pending_futures, f); 444 _pending_futures = eina_list_remove(_pending_futures, f);
445 eina_lock_release(&_pending_futures_lock);
440 } 446 }
441 447
442 if (f->promise) 448 if (f->promise)
@@ -470,7 +476,9 @@ _eina_future_schedule(Eina_Promise *p,
470 f, value); 476 f, value);
471 EINA_SAFETY_ON_NULL_GOTO(f->scheduled_entry, err); 477 EINA_SAFETY_ON_NULL_GOTO(f->scheduled_entry, err);
472 assert(f->scheduled_entry->scheduler != NULL); 478 assert(f->scheduled_entry->scheduler != NULL);
479 eina_lock_take(&_pending_futures_lock);
473 _pending_futures = eina_list_append(_pending_futures, f); 480 _pending_futures = eina_list_append(_pending_futures, f);
481 eina_lock_release(&_pending_futures_lock);
474 DBG("The promise %p schedule the future %p with cb: %p and data: %p", 482 DBG("The promise %p schedule the future %p with cb: %p and data: %p",
475 p, f, f->cb, f->data); 483 p, f, f->cb, f->data);
476 return; 484 return;
@@ -523,6 +531,8 @@ eina_promise_init(void)
523 NULL, sizeof(Eina_Future), 512); 531 NULL, sizeof(Eina_Future), 512);
524 EINA_SAFETY_ON_NULL_GOTO(_future_mp, err_future); 532 EINA_SAFETY_ON_NULL_GOTO(_future_mp, err_future);
525 533
534 eina_lock_recursive_new(&_pending_futures_lock);
535
526 return EINA_TRUE; 536 return EINA_TRUE;
527 537
528 err_future: 538 err_future:
@@ -537,14 +547,17 @@ eina_promise_init(void)
537EAPI void 547EAPI void
538__eina_promise_cancel_all(void) 548__eina_promise_cancel_all(void)
539{ 549{
550 eina_lock_take(&_pending_futures_lock);
540 while (_pending_futures) 551 while (_pending_futures)
541 _eina_future_cancel(_pending_futures->data, ECANCELED); 552 _eina_future_cancel(_pending_futures->data, ECANCELED);
553 eina_lock_release(&_pending_futures_lock);
542} 554}
543 555
544Eina_Bool 556Eina_Bool
545eina_promise_shutdown(void) 557eina_promise_shutdown(void)
546{ 558{
547 __eina_promise_cancel_all(); 559 __eina_promise_cancel_all();
560 eina_lock_free(&_pending_futures_lock);
548 eina_mempool_del(_future_mp); 561 eina_mempool_del(_future_mp);
549 eina_mempool_del(_promise_mp); 562 eina_mempool_del(_promise_mp);
550 eina_log_domain_unregister(_promise_log_dom); 563 eina_log_domain_unregister(_promise_log_dom);