summaryrefslogtreecommitdiff
path: root/src/lib/ecore
diff options
context:
space:
mode:
authorGuilherme Iscaro <iscaro@profusion.mobi>2017-08-08 18:10:36 -0300
committerGuilherme Iscaro <iscaro@profusion.mobi>2017-09-04 10:24:00 -0300
commit5bd8c9a78d7bc21a956b775fb250e8e14711d5b9 (patch)
tree5a3b270ecd53a712b66ad32e2989091250418423 /src/lib/ecore
parentc9a0237770a7fb0f1d94c9f99b7cab68399a922f (diff)
Eina: Add Eina_Promise/Eina_Future.
This commit adds a new promise/future API which aims to replace efl_future.
Diffstat (limited to 'src/lib/ecore')
-rw-r--r--src/lib/ecore/ecore.c1
-rw-r--r--src/lib/ecore/ecore_events.c111
-rw-r--r--src/lib/ecore/ecore_main.c7
-rw-r--r--src/lib/ecore/ecore_private.h4
-rw-r--r--src/lib/ecore/efl_loop.eo13
5 files changed, 136 insertions, 0 deletions
diff --git a/src/lib/ecore/ecore.c b/src/lib/ecore/ecore.c
index aa5e4e4f3c..ec733b20c6 100644
--- a/src/lib/ecore/ecore.c
+++ b/src/lib/ecore/ecore.c
@@ -251,6 +251,7 @@ ecore_init(void)
251 if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1; 251 if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
252 if (_ecore_fps_debug) _ecore_fps_debug_init(); 252 if (_ecore_fps_debug) _ecore_fps_debug_init();
253 if (!ecore_mempool_init()) goto shutdown_mempool; 253 if (!ecore_mempool_init()) goto shutdown_mempool;
254 if (!_ecore_event_init()) goto shutdown_mempool;
254 _ecore_main_loop_init(); 255 _ecore_main_loop_init();
255 256
256 vpath = efl_add(EFL_VPATH_CORE_CLASS, NULL); 257 vpath = efl_add(EFL_VPATH_CORE_CLASS, NULL);
diff --git a/src/lib/ecore/ecore_events.c b/src/lib/ecore/ecore_events.c
index 3b13ef9015..ed405edb39 100644
--- a/src/lib/ecore/ecore_events.c
+++ b/src/lib/ecore/ecore_events.c
@@ -48,6 +48,15 @@ struct _Ecore_Event
48}; 48};
49GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event); 49GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event);
50 50
51typedef struct _Ecore_Future_Schedule_Entry
52{
53 Eina_Future_Schedule_Entry base;
54 Eina_Future_Scheduler_Cb cb;
55 Eina_Future *future;
56 Ecore_Event *event;
57 Eina_Value value;
58} Ecore_Future_Schedule_Entry;
59
51static int events_num = 0; 60static int events_num = 0;
52static Ecore_Event *events = NULL; 61static Ecore_Event *events = NULL;
53static Ecore_Event *event_current = NULL; 62static Ecore_Event *event_current = NULL;
@@ -68,6 +77,10 @@ static int event_filters_delete_me = 0;
68static int event_id_max = ECORE_EVENT_COUNT; 77static int event_id_max = ECORE_EVENT_COUNT;
69static int ecore_raw_event_type = ECORE_EVENT_NONE; 78static int ecore_raw_event_type = ECORE_EVENT_NONE;
70static void *ecore_raw_event_event = NULL; 79static void *ecore_raw_event_event = NULL;
80static Ecore_Event_Handler *future_handler = NULL;
81static int ECORE_EV_FUTURE_ID = -1;
82static Eina_Mempool *mp_future_schedule_entry = NULL;
83static Eina_Bool shutting_down = EINA_FALSE;
71 84
72static void _ecore_event_purge_deleted(void); 85static void _ecore_event_purge_deleted(void);
73static void *_ecore_event_del(Ecore_Event *event); 86static void *_ecore_event_del(Ecore_Event *event);
@@ -268,6 +281,100 @@ _ecore_event_handler_del(Ecore_Event_Handler *event_handler)
268 return event_handler->data; 281 return event_handler->data;
269} 282}
270 283
284static Eina_Bool
285ecore_future_dispatched(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
286{
287 Ecore_Future_Schedule_Entry *entry = event;
288 entry->event = NULL;
289 entry->cb(entry->future, entry->value);
290 return EINA_FALSE;
291}
292
293static void
294ecore_future_free(void *user_data, void *func_data EINA_UNUSED)
295{
296 Ecore_Future_Schedule_Entry *entry = user_data;
297 /*
298 In case entry->event is not NULL, it means
299 that ecore is shutting down. In this case,
300 we must cancel the future otherwise Eina may
301 try to use it and lead to crashes.
302 */
303 if (entry->event)
304 {
305 eina_future_cancel(entry->future);
306 eina_value_flush(&entry->value);
307 }
308 eina_mempool_free(mp_future_schedule_entry, entry);
309}
310
311static Eina_Future_Schedule_Entry *
312ecore_future_schedule(Eina_Future_Scheduler *sched, Eina_Future_Scheduler_Cb cb, Eina_Future *future, Eina_Value value)
313{
314 Ecore_Future_Schedule_Entry *entry = eina_mempool_malloc(mp_future_schedule_entry,
315 sizeof(Ecore_Future_Schedule_Entry));
316 EINA_SAFETY_ON_NULL_RETURN_VAL(entry, NULL);
317 entry->base.scheduler = sched;
318 entry->cb = cb;
319 entry->future = future;
320 entry->value = value;
321 entry->event = ecore_event_add(ECORE_EV_FUTURE_ID, entry, ecore_future_free, entry);
322 EINA_SAFETY_ON_NULL_GOTO(entry->event, err);
323 return &entry->base;
324
325 err:
326 eina_mempool_free(mp_future_schedule_entry, entry);
327 return NULL;
328}
329
330static void
331ecore_future_recall(Eina_Future_Schedule_Entry *s_entry)
332{
333 if (shutting_down) return;
334 Ecore_Future_Schedule_Entry *entry = (Ecore_Future_Schedule_Entry *)s_entry;
335 EINA_SAFETY_ON_NULL_RETURN(entry->event);
336 ecore_event_del(entry->event);
337 eina_value_flush(&entry->value);
338 entry->event = NULL;
339}
340
341static Eina_Future_Scheduler ecore_future_scheduler = {
342 .schedule = ecore_future_schedule,
343 .recall = ecore_future_recall,
344};
345
346Eina_Future_Scheduler *
347_ecore_event_future_scheduler_get(void)
348{
349 return &ecore_future_scheduler;
350}
351
352Eina_Bool
353_ecore_event_init(void)
354{
355 const char *choice = getenv("EINA_MEMPOOL");
356 if ((!choice) || (!choice[0])) choice = "chained_mempool";
357
358 shutting_down = EINA_FALSE;
359 ECORE_EV_FUTURE_ID = ecore_event_type_new();
360 future_handler = ecore_event_handler_add(ECORE_EV_FUTURE_ID, ecore_future_dispatched, NULL);
361 EINA_SAFETY_ON_NULL_GOTO(future_handler, err_handler);
362 //FIXME: Is 512 too high?
363 mp_future_schedule_entry = eina_mempool_add(choice, "Ecore_Future_Event",
364 NULL, sizeof(Ecore_Future_Schedule_Entry),
365 512);
366 EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool);
367
368 return EINA_TRUE;
369
370 err_pool:
371 ecore_event_handler_del(future_handler);
372 future_handler = NULL;
373 err_handler:
374 ECORE_EV_FUTURE_ID = -1;
375 return EINA_FALSE;
376}
377
271void 378void
272_ecore_event_shutdown(void) 379_ecore_event_shutdown(void)
273{ 380{
@@ -275,6 +382,9 @@ _ecore_event_shutdown(void)
275 Ecore_Event_Handler *eh; 382 Ecore_Event_Handler *eh;
276 Ecore_Event_Filter *ef; 383 Ecore_Event_Filter *ef;
277 384
385 shutting_down = EINA_TRUE;
386 ecore_event_handler_del(future_handler);
387 future_handler = NULL;
278 while (events) _ecore_event_del(events); 388 while (events) _ecore_event_del(events);
279 event_current = NULL; 389 event_current = NULL;
280 for (i = 0; i < event_handlers_num; i++) 390 for (i = 0; i < event_handlers_num; i++)
@@ -301,6 +411,7 @@ _ecore_event_shutdown(void)
301 event_filters_delete_me = 0; 411 event_filters_delete_me = 0;
302 event_filter_current = NULL; 412 event_filter_current = NULL;
303 event_filter_event_current = NULL; 413 event_filter_event_current = NULL;
414 ECORE_EV_FUTURE_ID = -1;
304} 415}
305 416
306int 417int
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index 12e8cf450f..0bb15e0c02 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -3286,5 +3286,12 @@ _efl_loop_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
3286 return &version; 3286 return &version;
3287} 3287}
3288 3288
3289EOLIAN static Eina_Future_Scheduler *
3290_efl_loop_future_scheduler_get(Eo *obj EINA_UNUSED,
3291 Efl_Loop_Data *pd EINA_UNUSED)
3292{
3293 return _ecore_event_future_scheduler_get();
3294}
3295
3289 3296
3290#include "efl_loop.eo.c" 3297#include "efl_loop.eo.c"
diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h
index de6838b8b2..6437b41fb2 100644
--- a/src/lib/ecore/ecore_private.h
+++ b/src/lib/ecore/ecore_private.h
@@ -187,6 +187,10 @@ void _ecore_idle_enterer_call(Eo *loop);
187 187
188void _ecore_idle_exiter_call(Eo *loop); 188void _ecore_idle_exiter_call(Eo *loop);
189 189
190
191Eina_Future_Scheduler *_ecore_event_future_scheduler_get(void);
192
193Eina_Bool _ecore_event_init(void);
190void _ecore_event_shutdown(void); 194void _ecore_event_shutdown(void);
191int _ecore_event_exist(void); 195int _ecore_event_exist(void);
192Ecore_Event *_ecore_event_add(int type, 196Ecore_Event *_ecore_event_add(int type,
diff --git a/src/lib/ecore/efl_loop.eo b/src/lib/ecore/efl_loop.eo
index aa8ae08d4c..e34deb586f 100644
--- a/src/lib/ecore/efl_loop.eo
+++ b/src/lib/ecore/efl_loop.eo
@@ -1,4 +1,5 @@
1import efl_types; 1import efl_types;
2import eina_types;
2 3
3struct Efl.Loop.Arguments { 4struct Efl.Loop.Arguments {
4 [[EFL loop arguments data structure]] 5 [[EFL loop arguments data structure]]
@@ -69,6 +70,18 @@ class Efl.Loop (Efl.Object)
69 @in exit_code: ubyte; [[Returned value by begin()]] 70 @in exit_code: ubyte; [[Returned value by begin()]]
70 } 71 }
71 } 72 }
73 @property future_scheduler {
74 [[Gets the Eina_Future_Scheduler for a given mainloop.
75
76 The Eina_Future_Scheduler returned by this function
77 should be used for creating promises (eina_promise_new())
78 so then can properly schedule resolve/reject events.
79 ]]
80 get {}
81 values {
82 scheduler: ptr(Eina.Future.Scheduler); [[The scheduler.]]
83 }
84 }
72 job { 85 job {
73 [[Will execute that promise in the near future.]] 86 [[Will execute that promise in the near future.]]
74 params { 87 params {