summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ecore/Ecore_Eo.h7
-rw-r--r--src/lib/ecore/ecore.c11
-rw-r--r--src/lib/ecore/ecore_alloc.c18
-rw-r--r--src/lib/ecore/ecore_event_message.c81
-rw-r--r--src/lib/ecore/ecore_event_message.eo34
-rw-r--r--src/lib/ecore/ecore_event_message_handler.c414
-rw-r--r--src/lib/ecore/ecore_event_message_handler.eo86
-rw-r--r--src/lib/ecore/ecore_events.c644
-rw-r--r--src/lib/ecore/ecore_exe.c163
-rw-r--r--src/lib/ecore/ecore_exe_posix.c1562
-rw-r--r--src/lib/ecore/ecore_exe_private.h7
-rw-r--r--src/lib/ecore/ecore_exe_win32.c7
-rw-r--r--src/lib/ecore/ecore_job.c2
-rw-r--r--src/lib/ecore/ecore_main.c3221
-rw-r--r--src/lib/ecore/ecore_main_common.h96
-rw-r--r--src/lib/ecore/ecore_main_timechanges.c88
-rw-r--r--src/lib/ecore/ecore_pipe.c350
-rw-r--r--src/lib/ecore/ecore_private.h170
-rw-r--r--src/lib/ecore/ecore_signal.c99
-rw-r--r--src/lib/ecore/ecore_time.c44
-rw-r--r--src/lib/ecore/ecore_timer.c433
-rw-r--r--src/lib/ecore/efl_loop.c717
-rw-r--r--src/lib/ecore/efl_loop.eo37
-rw-r--r--src/lib/ecore/efl_loop_handler.c341
-rw-r--r--src/lib/ecore/efl_loop_handler.eo72
-rw-r--r--src/lib/ecore/efl_loop_message.c83
-rw-r--r--src/lib/ecore/efl_loop_message.eo13
-rw-r--r--src/lib/ecore/efl_loop_message_handler.c145
-rw-r--r--src/lib/ecore/efl_loop_message_handler.eo38
-rw-r--r--src/lib/ecore/efl_promise.c36
-rw-r--r--src/lib/ecore/efl_promise.eo1
31 files changed, 5048 insertions, 3972 deletions
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index 9203bf1e4d..be1929aa42 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -29,12 +29,18 @@
*/
+#include "ecore_event_message.eo.h"
+#include "ecore_event_message_handler.eo.h"
+
/**
* @ingroup Ecore_MainLoop_Group
*
* @{
*/
+#include "efl_loop_message.eo.h"
+#include "efl_loop_message_handler.eo.h"
+
#include "efl_loop.eo.h"
/**
@@ -56,6 +62,7 @@ EAPI int efl_loop_exit_code_process(Eina_Value *value);
EAPI Eina_Future_Scheduler *efl_loop_future_scheduler_get(Eo *obj);
#include "efl_loop_fd.eo.h"
+#include "efl_loop_handler.eo.h"
#include "efl_promise.eo.h"
diff --git a/src/lib/ecore/ecore.c b/src/lib/ecore/ecore.c
index 97dc4b2aa3..0c19d4b482 100644
--- a/src/lib/ecore/ecore.c
+++ b/src/lib/ecore/ecore.c
@@ -273,14 +273,12 @@ ecore_init(void)
if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
if (_ecore_fps_debug) _ecore_fps_debug_init();
if (!ecore_mempool_init()) goto shutdown_mempool;
- if (!_ecore_event_init()) goto shutdown_mempool;
_ecore_main_loop_init();
+ if (!_ecore_event_init()) goto shutdown_event;
vpath = efl_add(EFL_VPATH_CORE_CLASS, NULL);
if (vpath) efl_vpath_manager_register(EFL_VPATH_MANAGER_CLASS, 0, vpath);
- _mainloop_singleton = efl_add(EFL_LOOP_CLASS, NULL);
-
_ecore_signal_init();
#ifndef HAVE_EXOTIC
_ecore_exe_init();
@@ -359,6 +357,9 @@ ecore_init(void)
return _ecore_init_count;
+shutdown_event:
+ _ecore_event_shutdown();
+ _ecore_main_shutdown();
shutdown_mempool:
ecore_mempool_shutdown();
efl_object_shutdown();
@@ -403,9 +404,6 @@ ecore_shutdown(void)
}
#endif
- efl_del(_mainloop_singleton);
- _mainloop_singleton = NULL;
-
if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
_ecore_poller_shutdown();
_ecore_animator_shutdown();
@@ -442,7 +440,6 @@ ecore_shutdown(void)
#ifndef HAVE_EXOTIC
_ecore_exe_shutdown();
#endif
- _efl_loop_timer_shutdown();
_ecore_event_shutdown();
_ecore_main_shutdown();
_ecore_signal_shutdown();
diff --git a/src/lib/ecore/ecore_alloc.c b/src/lib/ecore/ecore_alloc.c
index 3196b82a2d..c98ef92335 100644
--- a/src/lib/ecore/ecore_alloc.c
+++ b/src/lib/ecore/ecore_alloc.c
@@ -33,9 +33,9 @@ struct _Ecore_Mempool
}
//GENERIC_ALLOC_FREE(Ecore_Animator, ecore_animator);
-GENERIC_ALLOC_FREE(Ecore_Event_Handler, ecore_event_handler);
-GENERIC_ALLOC_FREE(Ecore_Event_Filter, ecore_event_filter);
-GENERIC_ALLOC_FREE(Ecore_Event, ecore_event);
+//GENERIC_ALLOC_FREE(Ecore_Event_Handler, ecore_event_handler);
+//GENERIC_ALLOC_FREE(Ecore_Event_Filter, ecore_event_filter);
+//GENERIC_ALLOC_FREE(Ecore_Event, ecore_event);
//GENERIC_ALLOC_FREE(Ecore_Idle_Exiter, ecore_idle_exiter);
//GENERIC_ALLOC_FREE(Ecore_Idle_Enterer, ecore_idle_enterer);
//GENERIC_ALLOC_FREE(Ecore_Idler, ecore_idler);
@@ -51,9 +51,9 @@ GENERIC_ALLOC_FREE(Ecore_Win32_Handler, ecore_win32_handler);
static Ecore_Mempool *mempool_array[] = {
// &ecore_animator_mp,
- &ecore_event_handler_mp,
- &ecore_event_filter_mp,
- &ecore_event_mp,
+// &ecore_event_handler_mp,
+// &ecore_event_filter_mp,
+// &ecore_event_mp,
// &ecore_idle_exiter_mp,
// &ecore_idle_enterer_mp,
// &ecore_idler_mp,
@@ -78,9 +78,9 @@ ecore_mempool_init(void)
Type##_mp.size = _ecore_sizeof_##TYPE
// MP_SIZE_INIT(Ecore_Animator, ecore_animator);
- MP_SIZE_INIT(Ecore_Event_Handler, ecore_event_handler);
- MP_SIZE_INIT(Ecore_Event_Filter, ecore_event_filter);
- MP_SIZE_INIT(Ecore_Event, ecore_event);
+// MP_SIZE_INIT(Ecore_Event_Handler, ecore_event_handler);
+// MP_SIZE_INIT(Ecore_Event_Filter, ecore_event_filter);
+// MP_SIZE_INIT(Ecore_Event, ecore_event);
// MP_SIZE_INIT(Ecore_Idle_Exiter, ecore_idle_exiter);
// MP_SIZE_INIT(Ecore_Idle_Enterer, ecore_idle_enterer);
// MP_SIZE_INIT(Ecore_Idler, ecore_idler);
diff --git a/src/lib/ecore/ecore_event_message.c b/src/lib/ecore/ecore_event_message.c
new file mode 100644
index 0000000000..ca072f8524
--- /dev/null
+++ b/src/lib/ecore/ecore_event_message.c
@@ -0,0 +1,81 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+
+#include "ecore_private.h"
+
+#define MY_CLASS ECORE_EVENT_MESSAGE_CLASS
+
+//////////////////////////////////////////////////////////////////////////
+
+typedef struct _Ecore_Event_Message_Data Ecore_Event_Message_Data;
+
+struct _Ecore_Event_Message_Data
+{
+ int type;
+ void *ev;
+ Ecore_End_Cb free_func;
+ void *data;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+EOLIAN static void
+_ecore_event_message_data_set(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd, int type, void *data, void *free_func, void *free_data)
+{
+ pd->type = type;
+ pd->ev = data;
+ pd->free_func = free_func;
+ pd->data = free_data;
+}
+
+EOLIAN static void
+_ecore_event_message_data_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd, int *type, void **data, void **free_func, void **free_data)
+{
+ if (type) *type = pd->type;
+ if (data) *data = pd->ev;
+ if (free_func) *free_func = pd->free_func;
+ if (free_data) *free_data = pd->data;
+}
+
+EOLIAN static void
+_ecore_event_message_data_steal(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd, int *type, void **data, void **free_func, void **free_data)
+{
+ if (type) *type = pd->type;
+ if (data) *data = pd->ev;
+ if (free_func) *free_func = pd->free_func;
+ if (free_data) *free_data = pd->data;
+ pd->type = -1;
+ pd->ev = NULL;
+ pd->free_func = NULL;
+ pd->data = NULL;
+}
+
+EOLIAN static Efl_Object *
+_ecore_event_message_efl_object_constructor(Eo *obj, Ecore_Event_Message_Data *pd EINA_UNUSED)
+{
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+ pd->type = -1;
+ return obj;
+}
+
+EOLIAN static void
+_ecore_event_message_efl_object_destructor(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd EINA_UNUSED)
+{
+ if (pd->ev)
+ {
+ Ecore_End_Cb fn_free = pd->free_func;
+ void *ev = pd->ev;
+
+ pd->ev = NULL;
+ if (fn_free) fn_free(pd->data, ev);
+ else free(ev);
+ }
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "ecore_event_message.eo.c"
diff --git a/src/lib/ecore/ecore_event_message.eo b/src/lib/ecore/ecore_event_message.eo
new file mode 100644
index 0000000000..002197a122
--- /dev/null
+++ b/src/lib/ecore/ecore_event_message.eo
@@ -0,0 +1,34 @@
+import efl_types;
+import eina_types;
+
+class Ecore.Event.Message (Efl.Loop.Message)
+{
+ [[ For Legacy API usage Only. Legacy Ecore Events ]]
+ methods {
+ @property data {
+ [[ Property of the legacy event - set and get it ]]
+ set { }
+ get { }
+ values {
+ type: int; [[ The event type ]]
+ data: void_ptr; [[ The event data ]]
+ free_func: void_ptr; [[ Being lazy for legacy ]]
+ free_data: void_ptr; [[ Free func data ]]
+ }
+ }
+ data_steal {
+ [[ Steal the data out and set internal values to -1
+ for type and NULL for other vals ]]
+ params {
+ @out type: int; [[ The event type ]]
+ @out data: void_ptr; [[ The event data ]]
+ @out free_func: void_ptr; [[ Being lazy for legacy ]]
+ @out free_data: void_ptr; [[ Free func data ]]
+ }
+ }
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ }
+}
diff --git a/src/lib/ecore/ecore_event_message_handler.c b/src/lib/ecore/ecore_event_message_handler.c
new file mode 100644
index 0000000000..3879c3c78e
--- /dev/null
+++ b/src/lib/ecore/ecore_event_message_handler.c
@@ -0,0 +1,414 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+
+#include "ecore_private.h"
+
+#define MY_CLASS ECORE_EVENT_MESSAGE_HANDLER_CLASS
+
+//////////////////////////////////////////////////////////////////////////
+
+typedef struct _Handler Handler;
+typedef struct _Filter Filter;
+
+struct _Handler
+{
+ EINA_INLIST;
+ Ecore_Event_Handler_Cb func;
+ void *data;
+ int type;
+ Eina_Bool delete_me : 1;
+ Eina_Bool to_add : 1;
+};
+
+struct _Filter
+{
+ EINA_INLIST;
+ Ecore_Data_Cb func_start;
+ Ecore_Filter_Cb func_filter;
+ Ecore_End_Cb func_end;
+ void *data;
+ void *loop_data;
+ Eina_Bool delete_me : 1;
+};
+
+typedef struct _Ecore_Event_Message_Handler_Data Ecore_Event_Message_Handler_Data;
+
+struct _Ecore_Event_Message_Handler_Data
+{
+ int event_type_count;
+ Eina_Inlist **handlers; // array of event_type_count inlists of handlers
+ Eina_Inlist *filters;
+ Eina_List *handlers_delete;
+ Eina_List *handlers_add;
+ Eina_List *filters_delete;
+ Eina_List *filters_add;
+ void *current_event_data;
+ int current_event_type;
+ int handlers_walking;
+ int filters_walking;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+Eina_Bool
+_ecore_event_do_filter(void *handler_pd, Eo *msg_handler, Eo *msg)
+{
+ Filter *f;
+ void *ev;
+ int type;
+ Ecore_Event_Message_Handler_Data *eemhd = handler_pd;
+
+ if (!eemhd->filters) return EINA_TRUE;
+ if (!efl_isa(msg_handler, MY_CLASS)) return EINA_TRUE;
+ eemhd->filters_walking++;
+ EINA_INLIST_FOREACH(eemhd->filters, f)
+ {
+ if (f->delete_me) continue;
+ type = -1;
+ ev = NULL;
+ ecore_event_message_data_get(msg, &type, &ev, NULL, NULL);
+ if (type >= 0)
+ {
+ if (!f->func_filter(f->data, f->loop_data, type, ev))
+ _efl_loop_message_unsend(msg);
+ }
+ }
+ eemhd->filters_walking--;
+ return EINA_TRUE;
+}
+
+void
+_ecore_event_filters_call(Eo *obj, Efl_Loop_Data *pd)
+{
+ Filter *f;
+ Ecore_Event_Message_Handler_Data *eemhd;
+ Eo *ecore_event_handler = efl_loop_message_handler_get
+ (EFL_LOOP_CLASS, obj, ECORE_EVENT_MESSAGE_HANDLER_CLASS);
+
+ if (!ecore_event_handler) return;
+ eemhd = efl_data_scope_get(ecore_event_handler, MY_CLASS);
+ if (!eemhd) return;
+ if (!eemhd->filters) return;
+ eemhd->filters_walking++;
+ EINA_INLIST_FOREACH(eemhd->filters, f)
+ {
+ if (f->delete_me) continue;
+ if (f->func_start) f->loop_data = f->func_start(f->data);
+ }
+ _efl_loop_messages_filter(obj, pd, eemhd);
+ EINA_INLIST_FOREACH(eemhd->filters, f)
+ {
+ if (f->delete_me) continue;
+ if (f->func_end) f->func_end(f->data, f->loop_data);
+ }
+ eemhd->filters_walking--;
+ if (eemhd->filters_walking == 0)
+ {
+ EINA_LIST_FREE(eemhd->filters_delete, f)
+ {
+ free(f);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+EOLIAN static Ecore_Event_Message *
+_ecore_event_message_handler_message_type_add(Eo *obj, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED)
+{
+ // XXX: implemented event obj cache
+ return efl_add(ECORE_EVENT_MESSAGE_CLASS, obj);
+}
+
+EOLIAN static int
+_ecore_event_message_handler_type_new(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd)
+{
+ Eina_Inlist **tmp;
+ int evnum;
+
+ evnum = pd->event_type_count + 1;
+ tmp = realloc(pd->handlers, sizeof(Eina_Inlist *) * (evnum + 1));
+ if (!tmp) return 0;
+ pd->handlers = tmp;
+ pd->handlers[evnum] = NULL;
+ pd->event_type_count = evnum;
+ return evnum;
+}
+
+EOLIAN static void *
+_ecore_event_message_handler_handler_add(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, int type, void *func, void *data)
+{
+ Handler *h;
+
+ if ((type < 0) || (type > pd->event_type_count) || (!func)) return NULL;
+ h = calloc(1, sizeof(Handler));
+ if (!h) return NULL;
+ h->func = func;
+ h->data = data;
+ h->type = type;
+ if (pd->current_event_type == type)
+ {
+ h->to_add = EINA_TRUE;
+ pd->handlers_add = eina_list_append(pd->handlers_add, h);
+ }
+ else
+ pd->handlers[type] = eina_inlist_append(pd->handlers[type],
+ EINA_INLIST_GET(h));
+ return h;
+}
+
+EOLIAN static void *
+_ecore_event_message_handler_handler_del(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, void *handler)
+{
+ Handler *h = handler;
+ void *data;
+
+ if (!h) return NULL;
+ if ((h->type < 0) || (h->type > pd->event_type_count)) return NULL;
+ data = h->data;
+ if (pd->handlers_walking > 0)
+ {
+ h->delete_me = EINA_TRUE;
+ pd->handlers_delete = eina_list_append(pd->handlers_delete, h);
+ }
+ else
+ {
+ if (h->to_add)
+ pd->handlers_add = eina_list_remove(pd->handlers_add, h);
+ else
+ pd->handlers[h->type] = eina_inlist_remove(pd->handlers[h->type],
+ EINA_INLIST_GET(h));
+ free(h);
+ }
+ return data;
+}
+
+EOLIAN static void *
+_ecore_event_message_handler_handler_data_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED, void *handler)
+{
+ Handler *h = handler;
+
+ if (!h) return NULL;
+ return h->data;
+}
+
+EOLIAN static void *
+_ecore_event_message_handler_handler_data_set(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED, void *handler, void *data)
+{
+ Handler *h = handler;
+ void *prev_data;
+
+ if (!h) return NULL;
+ prev_data = h->data;
+ h->data = data;
+ return prev_data;
+}
+
+EOLIAN static void *
+_ecore_event_message_handler_filter_add(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, void *func_start, void *func_filter, void *func_end, void *data)
+{
+ Filter *f;
+
+ if (!func_filter) return NULL;
+ f = calloc(1, sizeof(Filter));
+ if (!f) return NULL;
+ f->func_start = func_start;
+ f->func_filter = func_filter;
+ f->func_end = func_end;
+ f->data = data;
+ pd->filters = eina_inlist_append(pd->filters, EINA_INLIST_GET(f));
+ return f;
+}
+
+EOLIAN static void *
+_ecore_event_message_handler_filter_del(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, void *filter)
+{
+ Filter *f = filter;
+ void *data;
+
+ if (!f) return NULL;
+ data = f->data;
+ if (pd->filters_walking > 0)
+ {
+ f->delete_me = EINA_TRUE;
+ pd->filters_delete = eina_list_append(pd->filters_delete, f);
+ }
+ else
+ {
+ pd->filters = eina_inlist_remove(pd->filters, EINA_INLIST_GET(f));
+ free(f);
+ }
+ return data;
+}
+
+EOLIAN static int
+_ecore_event_message_handler_current_type_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd)
+{
+ return pd->current_event_type;
+}
+
+EOLIAN static void *
+_ecore_event_message_handler_current_event_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd)
+{
+ return pd->current_event_data;
+}
+
+EOLIAN static Efl_Object *
+_ecore_event_message_handler_efl_object_constructor(Eo *obj, Ecore_Event_Message_Handler_Data *pd)
+{
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+ pd->event_type_count = -1;
+ pd->current_event_type = -1;
+ return obj;
+}
+
+EOLIAN static void
+_ecore_event_message_handler_efl_object_destructor(Eo *obj, Ecore_Event_Message_Handler_Data *pd)
+{
+ Handler *h;
+ int i;
+
+ if (pd->handlers_walking == 0)
+ {
+ EINA_LIST_FREE(pd->handlers_delete, h)
+ {
+ pd->handlers[h->type] =
+ eina_inlist_remove(pd->handlers[h->type],
+ EINA_INLIST_GET(h));
+ free(h);
+ }
+ EINA_LIST_FREE(pd->handlers_add, h)
+ {
+ free(h);
+ }
+ for (i = 0; i < pd->event_type_count; i++)
+ {
+ EINA_INLIST_FREE(pd->handlers[i], h) free(h);
+ }
+ free(pd->handlers);
+ pd->handlers = NULL;
+ }
+ else
+ {
+ ERR("Destruction of ecore_event_message_handler while walking events");
+ }
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+EOLIAN static void
+_ecore_event_message_handler_efl_loop_message_handler_message_call(Eo *obj, Ecore_Event_Message_Handler_Data *pd, Efl_Loop_Message *message)
+{
+ Handler *h;
+ int type = -1;
+ void *data = NULL, *free_func = NULL, *free_data = NULL;
+ Ecore_End_Cb fn_free = NULL;
+ Eina_List *l, *l2;
+ int handled = 0;
+
+ // call legacy handlers which are controled by this class' custom api
+ ecore_event_message_data_steal
+ (message, &type, &data, &free_func, &free_data);
+ if ((type >= 0) && (type <= pd->event_type_count))
+ {
+ if (free_func) fn_free = free_func;
+ pd->current_event_data = data;
+ pd->current_event_type = type;
+ pd->handlers_walking++;
+ EINA_INLIST_FOREACH(pd->handlers[type], h)
+ {
+ if (h->delete_me) continue;
+ handled++;
+ if (!h->func(h->data, h->type, data)) break;
+ }
+ pd->handlers_walking--;
+ pd->current_event_data = NULL;
+ pd->current_event_type = -1;
+ EINA_LIST_FOREACH_SAFE(pd->handlers_add, l, l2, h)
+ {
+ if (h->type == type)
+ {
+ h->to_add = EINA_FALSE;
+ pd->handlers_add =
+ eina_list_remove_list(pd->handlers_add, l);
+ pd->handlers[type] =
+ eina_inlist_append(pd->handlers[type], EINA_INLIST_GET(h));
+ }
+ }
+ if (pd->handlers_walking == 0)
+ {
+ EINA_LIST_FREE(pd->handlers_delete, h)
+ {
+ if (h->to_add)
+ pd->handlers_add = eina_list_remove(pd->handlers_add, h);
+ else
+ pd->handlers[h->type] =
+ eina_inlist_remove(pd->handlers[h->type],
+ EINA_INLIST_GET(h));
+ free(h);
+ }
+ }
+ if ((type == ECORE_EVENT_SIGNAL_EXIT) && (handled == 0))
+ {
+ Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS);
+
+ if (loop)
+ {
+ Eina_Value v = EINA_VALUE_EMPTY;
+ int val = 0;
+
+ eina_value_setup(&v, EINA_VALUE_TYPE_INT);
+ eina_value_set(&v, &val);
+ efl_loop_quit(loop, v);
+ }
+ }
+ }
+
+ efl_event_callback_call
+ (obj, ECORE_EVENT_MESSAGE_HANDLER_EVENT_MESSAGE_ECORE_EVENT, message);
+ efl_loop_message_handler_message_call
+ (efl_super(obj, MY_CLASS), message);
+
+ if (data)
+ {
+ if (fn_free) fn_free(free_data, data);
+ else free(data);
+ }
+}
+
+static Eina_Bool
+_flush_cb(void *data, void *handler EINA_UNUSED, void *message)
+{
+ int *type = data;
+ int evtype = -1;
+ void *evdata = NULL, *free_func = NULL, *free_data = NULL;
+ Ecore_End_Cb fn_free = NULL;
+
+ if (!efl_isa(message, ECORE_EVENT_MESSAGE_CLASS)) return EINA_TRUE;
+ ecore_event_message_data_steal(message, &evtype, &evdata, &free_func, &free_data);
+ if (*type != evtype) return EINA_TRUE;
+ if (free_func)
+ {
+ fn_free = free_func;
+ fn_free(free_data, evdata);
+ }
+ return EINA_FALSE;
+}
+
+EOLIAN static void
+_ecore_event_message_handler_type_flush(Eo *obj, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED, int type)
+{
+ Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS);
+ Efl_Loop_Data *loop_data = efl_data_scope_get(loop, EFL_LOOP_CLASS);
+
+ if (loop && loop_data)
+ {
+ _efl_loop_messages_call(loop, loop_data, _flush_cb, &type);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+#include "ecore_event_message_handler.eo.c"
diff --git a/src/lib/ecore/ecore_event_message_handler.eo b/src/lib/ecore/ecore_event_message_handler.eo
new file mode 100644
index 0000000000..78047164ca
--- /dev/null
+++ b/src/lib/ecore/ecore_event_message_handler.eo
@@ -0,0 +1,86 @@
+import efl_types;
+import eina_types;
+
+class Ecore.Event.Message.Handler (Efl.Loop.Message.Handler)
+{
+ [[ For Legacy API usage Only
+ This class is rather hacky/messy as it's really internal glue
+ to handle legacy ecore events alongside the new loop message
+ stuff merged together. This is ugly as it's internal only
+ to quickly glue things together and is destined for death in
+ EFL 2.0 or when we dump legacy.
+ ]]
+ methods {
+ message_type_add {
+ [[ ]]
+ return: Ecore.Event.Message; [[ ]]
+ }
+ type_new {
+ [[ ]]
+ return: int; [[ ]]
+ }
+ handler_add {
+ [[ Legacy list of callback handlers so they can return false ]]
+ params {
+ type: int;
+ func: void_ptr;
+ data: void_ptr;
+ }
+ return: void_ptr; [[ Lazy return handle ]]
+ }
+ handler_del {
+ params {
+ handler: void_ptr; [[ handler returned from handler_add() ]]
+ }
+ return: void_ptr; [[ handler data ptr ]]
+ }
+ handler_data_get {
+ params {
+ handler: void_ptr; [[ handler returned from handler_add() ]]
+ }
+ return: void_ptr; [[ handler data ptr ]]
+ }
+ handler_data_set {
+ params {
+ handler: void_ptr; [[ handler returned from handler_add() ]]
+ data: void_ptr;
+ }
+ return: void_ptr; [[ prev handler data ptr ]]
+ }
+ filter_add {
+ [[ Legacy event filter ]]
+ params {
+ func_start: void_ptr;
+ func_filter: void_ptr;
+ func_end: void_ptr;
+ data: void_ptr;
+ }
+ return: void_ptr; [[ Lazy return filter handle ]]
+ }
+ filter_del {
+ params {
+ filter: void_ptr; [[ filter returned from filter_add() ]]
+ }
+ return: void_ptr; [[ filter data ptr ]]
+ }
+ current_type_get {
+ return: int; [[ ]]
+ }
+ current_event_get {
+ return: void_ptr; [[ ]]
+ }
+ type_flush {
+ params {
+ type: int; [[ the event type to flush ]]
+ }
+ }
+ }
+ events {
+ message,ecore,event: Ecore.Event.Message; [[ Sample - override this ]]
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ Efl.Loop.Message.Handler.message_call; [[ Sample - override this ]]
+ }
+}
diff --git a/src/lib/ecore/ecore_events.c b/src/lib/ecore/ecore_events.c
index ed405edb39..2a123a58fe 100644
--- a/src/lib/ecore/ecore_events.c
+++ b/src/lib/ecore/ecore_events.c
@@ -7,47 +7,6 @@
#include "Ecore.h"
#include "ecore_private.h"
-static int inpurge = 0;
-
-struct _Ecore_Event_Handler
-{
- EINA_INLIST;
- ECORE_MAGIC;
- int type;
- Ecore_Event_Handler_Cb func;
- void *data;
- int references;
- Eina_Bool delete_me : 1;
-};
-GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Handler);
-
-struct _Ecore_Event_Filter
-{
- EINA_INLIST;
- ECORE_MAGIC;
- Ecore_Data_Cb func_start;
- Ecore_Filter_Cb func_filter;
- Ecore_End_Cb func_end;
- void *loop_data;
- void *data;
- int references;
- Eina_Bool delete_me : 1;
-};
-GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Filter);
-
-struct _Ecore_Event
-{
- EINA_INLIST;
- ECORE_MAGIC;
- int type;
- void *event;
- Ecore_End_Cb func_free;
- void *data;
- int references;
- Eina_Bool delete_me : 1;
-};
-GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event);
-
typedef struct _Ecore_Future_Schedule_Entry
{
Eina_Future_Schedule_Entry base;
@@ -57,131 +16,45 @@ typedef struct _Ecore_Future_Schedule_Entry
Eina_Value value;
} Ecore_Future_Schedule_Entry;
-static int events_num = 0;
-static Ecore_Event *events = NULL;
-static Ecore_Event *event_current = NULL;
-static Ecore_Event *purge_events = NULL;
-
-static Ecore_Event_Handler **event_handlers = NULL;
-static Ecore_Event_Handler *event_handler_current = NULL;
-static int event_handlers_num = 0;
-static int event_handlers_alloc_num = 0;
-static Eina_List *event_handlers_delete_list = NULL;
-
-static Ecore_Event_Handler *event_handlers_add_list = NULL;
-
-static Ecore_Event_Filter *event_filters = NULL;
-static Ecore_Event_Filter *event_filter_current = NULL;
-static Ecore_Event *event_filter_event_current = NULL;
-static int event_filters_delete_me = 0;
-static int event_id_max = ECORE_EVENT_COUNT;
-static int ecore_raw_event_type = ECORE_EVENT_NONE;
-static void *ecore_raw_event_event = NULL;
-static Ecore_Event_Handler *future_handler = NULL;
-static int ECORE_EV_FUTURE_ID = -1;
-static Eina_Mempool *mp_future_schedule_entry = NULL;
-static Eina_Bool shutting_down = EINA_FALSE;
-
-static void _ecore_event_purge_deleted(void);
-static void *_ecore_event_del(Ecore_Event *event);
+//////
+// XXX: still using legacy ecore events
+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 Ecore_Event_Message_Handler *_event_msg_handler = NULL;
EAPI Ecore_Event_Handler *
ecore_event_handler_add(int type,
Ecore_Event_Handler_Cb func,
const void *data)
{
- Ecore_Event_Handler *eh = NULL;
-
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
-
- if (!func) return NULL;
- if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) return NULL;
- eh = ecore_event_handler_calloc(1);
- if (!eh) return NULL;
- ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER);
- eh->type = type;
- eh->func = func;
- eh->data = (void *)data;
- if (type >= (event_handlers_num - 1))
- {
- int p_alloc_num;
-
- p_alloc_num = event_handlers_alloc_num;
- event_handlers_num = type + 1;
- if (event_handlers_num > event_handlers_alloc_num)
- {
- Ecore_Event_Handler **new_handlers;
- int i;
-
- event_handlers_alloc_num = ((event_handlers_num + 16) / 16) * 16;
- new_handlers = realloc(event_handlers, event_handlers_alloc_num * sizeof(Ecore_Event_Handler *));
- if (!new_handlers)
- {
- ecore_event_handler_mp_free(eh);
- return NULL;
- }
- event_handlers = new_handlers;
- for (i = p_alloc_num; i < event_handlers_alloc_num; i++)
- event_handlers[i] = NULL;
- }
- }
- if (ecore_raw_event_type == type)
- event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh));
- else if (type < event_handlers_alloc_num)
- event_handlers[type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), EINA_INLIST_GET(eh));
-
- return eh;
+ return ecore_event_message_handler_add(_event_msg_handler,
+ type, func, (void *)data);
}
EAPI void *
ecore_event_handler_del(Ecore_Event_Handler *event_handler)
{
- if (!event_handler) return NULL;
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER))
- {
- ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER,
- "ecore_event_handler_del");
- return NULL;
- }
- return _ecore_event_handler_del(event_handler);
+ return ecore_event_message_handler_del(_event_msg_handler,
+ event_handler);
}
EAPI void *
ecore_event_handler_data_get(Ecore_Event_Handler *eh)
{
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER))
- {
- ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_get");
- return NULL;
- }
- return eh->data;
+ return ecore_event_message_handler_data_get(_event_msg_handler, eh);
}
EAPI void *
ecore_event_handler_data_set(Ecore_Event_Handler *eh,
const void *data)
{
- void *old = NULL;
-
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER))
- {
- ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_set");
- return NULL;
- }
- old = eh->data;
- eh->data = (void *)data;
-
- return old;
-}
-
-static void
-_ecore_event_generic_free(void *data EINA_UNUSED,
- void *event)
-{ /* DO NOT MEMPOOL FREE THIS */
- free(event);
+ return ecore_event_message_handler_data_set(_event_msg_handler, eh,
+ (void *)data);
}
EAPI Ecore_Event *
@@ -190,34 +63,27 @@ ecore_event_add(int type,
Ecore_End_Cb func_free,
void *data)
{
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
+ Ecore_Event_Message *msg;
- if (type <= ECORE_EVENT_NONE) return NULL;
- if (type >= event_id_max) return NULL;
- if ((ev) && (!func_free)) func_free = _ecore_event_generic_free;
- return _ecore_event_add(type, ev, func_free, data);
+ msg = ecore_event_message_handler_message_type_add(_event_msg_handler);
+ ecore_event_message_data_set(msg, type, ev, func_free, data);
+ efl_loop_message_handler_message_send(_event_msg_handler, msg);
+ return (Ecore_Event *)msg;
}
EAPI void *
ecore_event_del(Ecore_Event *event)
{
- if (!event) return NULL;
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT))
- {
- ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, "ecore_event_del");
- return NULL;
- }
- EINA_SAFETY_ON_TRUE_RETURN_VAL(event->delete_me, NULL);
- event->delete_me = 1;
- return event->data;
+ void *data = NULL;
+ ecore_event_message_data_get((Eo *)event, NULL, &data, NULL, NULL);
+ _efl_loop_message_unsend((Eo *)event);
+ return data;
}
EAPI int
ecore_event_type_new(void)
{
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
- return event_id_max++;
+ return ecore_event_message_handler_type_new(_event_msg_handler);
}
EAPI Ecore_Event_Filter *
@@ -226,59 +92,27 @@ ecore_event_filter_add(Ecore_Data_Cb func_start,
Ecore_End_Cb func_end,
const void *data)
{
- Ecore_Event_Filter *ef = NULL;
-
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- if (!func_filter) return NULL;
- ef = ecore_event_filter_calloc(1);
- if (!ef) return NULL;
- ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER);
- ef->func_start = func_start;
- ef->func_filter = func_filter;
- ef->func_end = func_end;
- ef->data = (void *)data;
- event_filters = (Ecore_Event_Filter *)eina_inlist_append(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
-
- return ef;
+ return ecore_event_message_handler_filter_add(_event_msg_handler,
+ func_start, func_filter,
+ func_end, (void *)data);
}
EAPI void *
ecore_event_filter_del(Ecore_Event_Filter *ef)
{
- if (!ef) return NULL;
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER))
- {
- ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del");
- return NULL;
- }
- EINA_SAFETY_ON_TRUE_RETURN_VAL(ef->delete_me, NULL);
- ef->delete_me = 1;
- event_filters_delete_me = 1;
- return ef->data;
+ return ecore_event_message_handler_filter_del(_event_msg_handler, ef);
}
EAPI int
ecore_event_current_type_get(void)
{
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
- return ecore_raw_event_type;
+ return ecore_event_message_handler_current_type_get(_event_msg_handler);
}
EAPI void *
ecore_event_current_event_get(void)
{
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- return ecore_raw_event_event;
-}
-
-EAPI void *
-_ecore_event_handler_del(Ecore_Event_Handler *event_handler)
-{
- EINA_SAFETY_ON_TRUE_RETURN_VAL(event_handler->delete_me, NULL);
- event_handler->delete_me = 1;
- event_handlers_delete_list = eina_list_append(event_handlers_delete_list, event_handler);
- return event_handler->data;
+ return ecore_event_message_handler_current_event_get(_event_msg_handler);
}
static Eina_Bool
@@ -294,12 +128,6 @@ static void
ecore_future_free(void *user_data, void *func_data EINA_UNUSED)
{
Ecore_Future_Schedule_Entry *entry = user_data;
- /*
- In case entry->event is not NULL, it means
- that ecore is shutting down. In this case,
- we must cancel the future otherwise Eina may
- try to use it and lead to crashes.
- */
if (entry->event)
{
eina_future_cancel(entry->future);
@@ -355,6 +183,44 @@ _ecore_event_init(void)
const char *choice = getenv("EINA_MEMPOOL");
if ((!choice) || (!choice[0])) choice = "chained_mempool";
+ _event_msg_handler =
+ efl_loop_message_handler_get(EFL_LOOP_CLASS,
+ _mainloop_singleton,
+ ECORE_EVENT_MESSAGE_HANDLER_CLASS);
+ if (!_event_msg_handler)
+ {
+ ERR("Cannot create legacy ecore event message handler");
+ return EINA_FALSE;
+ }
+ // init some core legacy event types in t he same order and numbering as before
+ // ECORE_EVENT_NONE 0
+ // no need to do as ev types start at 1
+
+ // ECORE_EVENT_SIGNAL_USER 1
+ ecore_event_message_handler_type_new(_event_msg_handler);
+ // ECORE_EVENT_SIGNAL_HUP 2
+ ecore_event_message_handler_type_new(_event_msg_handler);
+ // ECORE_EVENT_SIGNAL_EXIT 3
+ ecore_event_message_handler_type_new(_event_msg_handler);
+ // ECORE_EVENT_SIGNAL_POWER 4
+ ecore_event_message_handler_type_new(_event_msg_handler);
+ // ECORE_EVENT_SIGNAL_REALTIME 5
+ ecore_event_message_handler_type_new(_event_msg_handler);
+ // ECORE_EVENT_MEMORY_STATE 6
+ ecore_event_message_handler_type_new(_event_msg_handler);
+ // ECORE_EVENT_POWER_STATE 7
+ ecore_event_message_handler_type_new(_event_msg_handler);
+ // ECORE_EVENT_LOCALE_CHANGED 8
+ ecore_event_message_handler_type_new(_event_msg_handler);
+ // ECORE_EVENT_HOSTNAME_CHANGED 9
+ ecore_event_message_handler_type_new(_event_msg_handler);
+ // ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED 10
+ ecore_event_message_handler_type_new(_event_msg_handler);
+ // ECORE_EVENT_COUNT 11
+ // no need to do as it was a count, nto an event
+
+ //////
+ // 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);
@@ -364,6 +230,8 @@ _ecore_event_init(void)
NULL, sizeof(Ecore_Future_Schedule_Entry),
512);
EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool);
+ //
+ //////
return EINA_TRUE;
@@ -378,337 +246,42 @@ _ecore_event_init(void)
void
_ecore_event_shutdown(void)
{
- int i;
- Ecore_Event_Handler *eh;
- Ecore_Event_Filter *ef;
-
shutting_down = EINA_TRUE;
+
+ //////
+ // XXX: ecore future still using legacy...
ecore_event_handler_del(future_handler);
future_handler = NULL;
- while (events) _ecore_event_del(events);
- event_current = NULL;
- for (i = 0; i < event_handlers_num; i++)
- {
- while ((eh = event_handlers[i]))
- {
- event_handlers[i] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[i]), EINA_INLIST_GET(event_handlers[i]));
- ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
- if (!eh->delete_me) ecore_event_handler_mp_free(eh);
- }
- }
- EINA_LIST_FREE(event_handlers_delete_list, eh)
- ecore_event_handler_mp_free(eh);
- if (event_handlers) free(event_handlers);
- event_handlers = NULL;
- event_handlers_num = 0;
- event_handlers_alloc_num = 0;
- while ((ef = event_filters))
- {
- event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(event_filters));
- ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
- ecore_event_filter_mp_free(ef);
- }
- event_filters_delete_me = 0;
- event_filter_current = NULL;
- event_filter_event_current = NULL;
ECORE_EV_FUTURE_ID = -1;
-}
-
-int
-_ecore_event_exist(void)
-{
- Ecore_Event *e;
- EINA_INLIST_FOREACH(events, e)
- if (!e->delete_me) return 1;
- return 0;
-}
-
-Ecore_Event *
-_ecore_event_add(int type,
- void *ev,
- Ecore_End_Cb func_free,
- void *data)
-{
- Ecore_Event *e;
-
- e = ecore_event_calloc(1);
- if (!e) return NULL;
- ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT);
- e->type = type;
- e->event = ev;
- e->func_free = func_free;
- e->data = data;
- if (inpurge > 0)
- {
- purge_events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(e));
- events_num++;
- }
- else
- {
- events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
- events_num++;
- }
- return e;
-}
-
-void *
-_ecore_event_del(Ecore_Event *event)
-{
- void *data;
-
- data = event->data;
- if (event->func_free) _ecore_call_end_cb(event->func_free, event->data, event->event);
- events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event));
- ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE);
- ecore_event_mp_free(event);
- events_num--;
- return data;
-}
-
-static void
-_ecore_event_purge_deleted(void)
-{
- Ecore_Event *itr = events;
+ //
+ //////
- inpurge++;
- while (itr)
- {
- Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next;
- if ((!itr->references) && (itr->delete_me))
- _ecore_event_del(itr);
- itr = next;
- }
- inpurge--;
- while (purge_events)
- {
- Ecore_Event *e = purge_events;
- purge_events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(purge_events));
- events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
- }
-}
-
-static inline void
-_ecore_event_filters_apply(void)
-{
- if (!event_filter_current)
- {
- /* regular main loop, start from head */
- event_filter_current = event_filters;
- }
- else
- {
- /* recursive main loop, continue from where we were */
- event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
- }
- if ((!event_filter_current) && (!event_filters_delete_me) && (!purge_events)) return;
- eina_evlog("+event_filter", NULL, 0.0, NULL);
- while (event_filter_current)
- {
- Ecore_Event_Filter *ef = event_filter_current;
-
- if (!ef->delete_me)
- {
- ef->references++;
-
- if (ef->func_start)
- ef->loop_data = _ecore_call_data_cb(ef->func_start, ef->data);
-
- if (!event_filter_event_current)
- {
- /* regular main loop, start from head */
- event_filter_event_current = events;
- }
- else
- {
- /* recursive main loop, continue from where we were */
- event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
- }
-
- while (event_filter_event_current)
- {
- Ecore_Event *e = event_filter_event_current;
-
- if (!_ecore_call_filter_cb(ef->func_filter, ef->data,
- ef->loop_data, e->type, e->event))
- {
- ecore_event_del(e);
- }
-
- if (event_filter_event_current) /* may have changed in recursive main loops */
- event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
- }
- if (ef->func_end)
- _ecore_call_end_cb(ef->func_end, ef->data, ef->loop_data);
-
- ef->references--;
- }
-
- if (event_filter_current) /* may have changed in recursive main loops */
- event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
- }
- eina_evlog("-event_filter", NULL, 0.0, NULL);
- if (event_filters_delete_me)
- {
- int deleted_in_use = 0;
- Ecore_Event_Filter *l;
- for (l = event_filters; l; )
- {
- Ecore_Event_Filter *ef = l;
- l = (Ecore_Event_Filter *)EINA_INLIST_GET(l)->next;
- if (ef->delete_me)
- {
- if (ef->references)
- {
- deleted_in_use++;
- continue;
- }
-
- event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
- ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
- ecore_event_filter_mp_free(ef);
- }
- }
- if (!deleted_in_use)
- event_filters_delete_me = 0;
- }
-}
-
-void
-_ecore_event_call(void)
-{
- Eina_List *l, *l_next;
- Ecore_Event_Handler *eh;
-
- _ecore_event_filters_apply();
-
- if (!event_current)
- {
- /* regular main loop, start from head */
- event_current = events;
- event_handler_current = NULL;
- }
- if ((!event_current) && (!event_handlers_delete_list)) return;
- eina_evlog("+events", NULL, 0.0, NULL);
- while (event_current)
- {
- Ecore_Event *e = event_current;
- int handle_count = 0;
-
- if (e->delete_me)
- {
- event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
- continue;
- }
-
- ecore_raw_event_type = e->type;
- ecore_raw_event_event = e->event;
- e->references++;
- if ((e->type >= 0) && (e->type < event_handlers_num))
- {
- if (!event_handler_current)
- {
- /* regular main loop, start from head */
- event_handler_current = event_handlers[e->type];
- }
- else
- {
- /* recursive main loop, continue from where we were */
- event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
- }
-
- while ((event_handler_current) && (!e->delete_me))
- {
- eh = event_handler_current;
- if (!eh->delete_me)
- {
- Eina_Bool ret;
-
- handle_count++;
-
- eh->references++;
- ret = _ecore_call_handler_cb(eh->func, eh->data, e->type, e->event);
- eh->references--;
-
- if (!ret)
- {
- event_handler_current = NULL;
- break; /* 0 == "call no further handlers" */
- }
- }
-
- if (event_handler_current) /* may have changed in recursive main loops */
- event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
- }
- }
- while (event_handlers_add_list)
- {
- eh = event_handlers_add_list;
- event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh));
- event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
- }
- /* if no handlers were set for EXIT signal - then default is */
- /* to quit the main loop */
- if ((e->type == ECORE_EVENT_SIGNAL_EXIT) && (handle_count == 0))
- ecore_main_loop_quit();
- e->references--;
- e->delete_me = 1;
-
- if (event_current) /* may have changed in recursive main loops */
- event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
- }
- eina_evlog("-events", NULL, 0.0, NULL);
-
- ecore_raw_event_type = ECORE_EVENT_NONE;
- ecore_raw_event_event = NULL;
-
- _ecore_event_purge_deleted();
-
- EINA_LIST_FOREACH_SAFE(event_handlers_delete_list, l, l_next, eh)
- {
- if (eh->references) continue;
-
- event_handlers_delete_list = eina_list_remove_list(event_handlers_delete_list, l);
-
- event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
- ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
- ecore_event_handler_mp_free(eh);
- }
+ efl_loop_message_handler_message_clear(_event_msg_handler);
+ _event_msg_handler = NULL;
}
void *
_ecore_event_signal_user_new(void)
{
- Ecore_Event_Signal_User *e;
-
- e = calloc(1, sizeof(Ecore_Event_Signal_User));
- return e;
+ return calloc(1, sizeof(Ecore_Event_Signal_User));
}
void *
_ecore_event_signal_hup_new(void)
{
- Ecore_Event_Signal_Hup *e;
-
- e = calloc(1, sizeof(Ecore_Event_Signal_Hup));
- return e;
+ return calloc(1, sizeof(Ecore_Event_Signal_Hup));
}
void *
_ecore_event_signal_exit_new(void)
{
- Ecore_Event_Signal_Exit *e;
-
- e = calloc(1, sizeof(Ecore_Event_Signal_Exit));
- return e;
+ return calloc(1, sizeof(Ecore_Event_Signal_Exit));
}
void *
_ecore_event_signal_power_new(void)
{
- Ecore_Event_Signal_Power *e;
-
- e = calloc(1, sizeof(Ecore_Event_Signal_Power));
- return e;
+ return calloc(1, sizeof(Ecore_Event_Signal_Power));
}
void *
@@ -720,58 +293,17 @@ _ecore_event_signal_realtime_new(void)
EAPI void
ecore_event_type_flush_internal(int type, ...)
{
- Eina_Inarray types;
- Ecore_Event *event;
- Eina_Inlist *l;
- int *itr;
va_list args;
- Eina_Bool wrong_type = EINA_FALSE;
- // In case of an empty list of event
if (type == ECORE_EVENT_NONE) return;
-
- eina_inarray_step_set(&types, sizeof (Eina_Inarray), sizeof (int), 4);
-
- eina_inarray_push(&types, &type);
+ ecore_event_message_handler_type_flush(_event_msg_handler, type);
va_start(args, type);
- do
+ for (;;)
{
type = va_arg(args, int);
- if (type == ECORE_EVENT_NONE) break ;
- eina_inarray_push(&types, &type);
+ if (type == ECORE_EVENT_NONE) break;
+ ecore_event_message_handler_type_flush(_event_msg_handler, type);
}
- while (1);
va_end(args);
-
- EINA_INARRAY_FOREACH(&types, itr)
- {
- if (*itr >= 0 && *itr < event_id_max) continue;
-
- ERR("Invalid event flush requested: %i", *itr);
- wrong_type = EINA_TRUE;
- }
-
- if (wrong_type)
- {
- eina_inarray_flush(&types);
- return ;
- }
-
- EINA_INLIST_FOREACH_SAFE((Eina_Inlist *) events, l, event)
- {
- Eina_Bool found = EINA_FALSE;
-
- EINA_INARRAY_FOREACH(&types, itr)
- if (event->type == *itr)
- found = EINA_TRUE;
- if (!found) continue ;
-
- if (event->delete_me) continue ;
- event->delete_me = 1;
- }
-
- _ecore_event_purge_deleted();
-
- eina_inarray_flush(&types);
}
diff --git a/src/lib/ecore/ecore_exe.c b/src/lib/ecore/ecore_exe.c
index 22486cd609..908f677539 100644
--- a/src/lib/ecore/ecore_exe.c
+++ b/src/lib/ecore/ecore_exe.c
@@ -38,8 +38,6 @@ EAPI int ECORE_EXE_EVENT_DEL = 0;
EAPI int ECORE_EXE_EVENT_DATA = 0;
EAPI int ECORE_EXE_EVENT_ERROR = 0;
-Eina_List *_ecore_exe_exes = NULL;
-
EAPI void
ecore_exe_run_priority_set(int pri)
{
@@ -63,18 +61,19 @@ ecore_exe_run(const char *exe_cmd,
}
EAPI Ecore_Exe *
-ecore_exe_pipe_run(const char *exe_cmd,
- Ecore_Exe_Flags flags,
- const void *data)
+ecore_exe_pipe_run(const char *exe_cmd,
+ Ecore_Exe_Flags flags,
+ const void *data)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- Ecore_Exe *ret = efl_add(MY_CLASS, NULL, ecore_obj_exe_command_set(efl_added, exe_cmd, flags));
+ Ecore_Exe *ret = efl_add(MY_CLASS, efl_loop_main_get(EFL_LOOP_CLASS),
+ ecore_obj_exe_command_set(efl_added, exe_cmd,
+ flags));
if (ret)
{
Ecore_Exe_Data *pd = efl_data_scope_get(ret, MY_CLASS);
pd->data = (void *) data;
}
-
return ret;
}
@@ -98,10 +97,7 @@ _ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
obj = efl_finalize(efl_super(obj, MY_CLASS));
-
- if (!obj)
- return obj;
-
+ if (!obj) return obj;
return _impl_ecore_exe_efl_object_finalize(obj, exe);
}
@@ -111,8 +107,7 @@ ecore_exe_callback_pre_free_set(Ecore_Exe *obj,
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return;
+ if (!efl_isa(obj, MY_CLASS)) return;
exe->pre_free_cb = func;
}
@@ -123,18 +118,15 @@ ecore_exe_send(Ecore_Exe *obj,
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return EINA_FALSE;
+ if (!efl_isa(obj, MY_CLASS)) return EINA_FALSE;
EINA_SAFETY_ON_TRUE_RETURN_VAL(size == 0, EINA_TRUE);
-
if (exe->close_stdin)
- {
- ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",
- exe, size, data);
- return EINA_FALSE;
- }
-
+ {
+ ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",
+ exe, size, data);
+ return EINA_FALSE;
+ }
return _impl_ecore_exe_send(obj, exe, data, size);
}
@@ -143,9 +135,7 @@ ecore_exe_close_stdin(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return;
-
+ if (!efl_isa(obj, MY_CLASS)) return;
exe->close_stdin = 1;
}
@@ -158,10 +148,9 @@ ecore_exe_auto_limits_set(Ecore_Exe *obj,
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return;
-
- _impl_ecore_exe_auto_limits_set(obj, exe, start_bytes, end_bytes, start_lines, end_lines);
+ if (!efl_isa(obj, MY_CLASS)) return;
+ _impl_ecore_exe_auto_limits_set(obj, exe, start_bytes, end_bytes,
+ start_lines, end_lines);
}
EAPI Ecore_Exe_Event_Data *
@@ -170,9 +159,7 @@ ecore_exe_event_data_get(Ecore_Exe *obj,
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return NULL;
-
+ if (!efl_isa(obj, MY_CLASS)) return NULL;
return _impl_ecore_exe_event_data_get(obj, exe, flags);
}
@@ -182,14 +169,10 @@ ecore_exe_tag_set(Ecore_Exe *obj,
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return;
-
+ if (!efl_isa(obj, MY_CLASS)) return;
IF_FREE(exe->tag);
- if (tag)
- exe->tag = strdup(tag);
- else
- exe->tag = NULL;
+ if (tag) exe->tag = strdup(tag);
+ else exe->tag = NULL;
}
EAPI const char *
@@ -197,9 +180,7 @@ ecore_exe_tag_get(const Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return NULL;
-
+ if (!efl_isa(obj, MY_CLASS)) return NULL;
return exe->tag;
}
@@ -208,12 +189,9 @@ ecore_exe_free(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return NULL;
-
+ if (!efl_isa(obj, MY_CLASS)) return NULL;
void *data = exe->data;
efl_del(obj);
-
return data;
}
@@ -221,7 +199,6 @@ EOLIAN static void
_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe)
{
efl_destructor(efl_super(obj, ECORE_EXE_CLASS));
-
_impl_ecore_exe_efl_object_destructor(obj, exe);
}
@@ -239,9 +216,7 @@ ecore_exe_pid_get(const Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return -1;
-
+ if (!efl_isa(obj, MY_CLASS)) return -1;
return exe->pid;
}
@@ -250,9 +225,7 @@ ecore_exe_cmd_get(const Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
const char *ret = NULL;
-
ecore_obj_exe_command_get(obj, &ret, NULL);
-
return ret;
}
@@ -261,9 +234,7 @@ ecore_exe_data_get(const Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return NULL;
-
+ if (!efl_isa(obj, MY_CLASS)) return NULL;
return exe->data;
}
@@ -274,9 +245,7 @@ ecore_exe_data_set(Ecore_Exe *obj,
void *ret;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return NULL;
-
+ if (!efl_isa(obj, MY_CLASS)) return NULL;
ret = exe->data;
exe->data = data;
return ret;
@@ -287,9 +256,7 @@ ecore_exe_flags_get(const Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return 0;
-
+ if (!efl_isa(obj, MY_CLASS)) return 0;
return exe->flags;
}
@@ -309,15 +276,8 @@ EOLIAN static void
_ecore_exe_efl_control_suspend_set(Eo *obj EINA_UNUSED, Ecore_Exe_Data *exe, Eina_Bool suspend)
{
EINA_MAIN_LOOP_CHECK_RETURN;
-
- if (suspend)
- {
- _impl_ecore_exe_pause(obj, exe);
- }
- else
- {
- _impl_ecore_exe_continue(obj, exe);
- }
+ if (suspend) _impl_ecore_exe_pause(obj, exe);
+ else _impl_ecore_exe_continue(obj, exe);
}
EAPI void
@@ -325,9 +285,7 @@ ecore_exe_interrupt(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return;
-
+ if (!efl_isa(obj, MY_CLASS)) return;
_impl_ecore_exe_interrupt(obj, exe);
}
@@ -336,9 +294,7 @@ ecore_exe_quit(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return;
-
+ if (!efl_isa(obj, MY_CLASS)) return;
_impl_ecore_exe_quit(obj, exe);
}
@@ -347,9 +303,7 @@ ecore_exe_terminate(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return;
-
+ if (!efl_isa(obj, MY_CLASS)) return;
_impl_ecore_exe_terminate(obj, exe);
}
@@ -358,9 +312,7 @@ ecore_exe_kill(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return;
-
+ if (!efl_isa(obj, MY_CLASS)) return;
_impl_ecore_exe_kill(obj, exe);
}
@@ -370,9 +322,7 @@ ecore_exe_signal(Ecore_Exe *obj,
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return;
-
+ if (!efl_isa(obj, MY_CLASS)) return;
_impl_ecore_exe_signal(obj, exe, num);
}
@@ -381,9 +331,7 @@ ecore_exe_hup(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (!efl_isa(obj, MY_CLASS))
- return;
-
+ if (!efl_isa(obj, MY_CLASS)) return;
_impl_ecore_exe_hup(obj, exe);
}
@@ -401,7 +349,9 @@ _ecore_exe_shutdown(void)
{
Ecore_Exe *exe = NULL;
Eina_List *l1, *l2;
- EINA_LIST_FOREACH_SAFE(_ecore_exe_exes, l1, l2, exe)
+ Efl_Loop_Data *loop = EFL_LOOP_DATA;
+
+ EINA_LIST_FOREACH_SAFE(loop->exes, l1, l2, exe)
ecore_exe_free(exe);
ecore_event_type_flush(ECORE_EXE_EVENT_ADD,
@@ -415,22 +365,20 @@ _ecore_exe_find(pid_t pid)
{
Eina_List *itr;
Ecore_Exe *obj;
+ Efl_Loop_Data *loop = EFL_LOOP_DATA;
- EINA_LIST_FOREACH(_ecore_exe_exes, itr, obj)
- {
- Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (exe->pid == pid)
- return obj;
- }
+ EINA_LIST_FOREACH(loop->exes, itr, obj)
+ {
+ Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
+ if (exe->pid == pid) return obj;
+ }
return NULL;
}
void *
_ecore_exe_event_del_new(void)
{
- Ecore_Exe_Event_Del *e;
-
- e = calloc(1, sizeof(Ecore_Exe_Event_Del));
+ Ecore_Exe_Event_Del *e = calloc(1, sizeof(Ecore_Exe_Event_Del));
return e;
}
@@ -438,11 +386,8 @@ void
_ecore_exe_event_del_free(void *data EINA_UNUSED,
void *ev)
{
- Ecore_Exe_Event_Del *e;
-
- e = ev;
- if (e->exe)
- ecore_exe_free(e->exe);
+ Ecore_Exe_Event_Del *e = ev;
+ if (e->exe) ecore_exe_free(e->exe);
free(e);
}
@@ -450,18 +395,14 @@ void
_ecore_exe_event_exe_data_free(void *data EINA_UNUSED,
void *ev)
{
- Ecore_Exe_Event_Data *e;
-
- e = ev;
+ Ecore_Exe_Event_Data *e = ev;
ecore_exe_event_data_free(e);
}
Ecore_Exe_Event_Add *
_ecore_exe_event_add_new(void)
{
- Ecore_Exe_Event_Add *e;
-
- e = calloc(1, sizeof(Ecore_Exe_Event_Add));
+ Ecore_Exe_Event_Add *e = calloc(1, sizeof(Ecore_Exe_Event_Add));
return e;
}
@@ -469,9 +410,7 @@ void
_ecore_exe_event_add_free(void *data EINA_UNUSED,
void *ev)
{
- Ecore_Exe_Event_Add *e;
-
- e = ev;
+ Ecore_Exe_Event_Add *e = ev;
free(e);
}
diff --git a/src/lib/ecore/ecore_exe_posix.c b/src/lib/ecore/ecore_exe_posix.c
index bebfce26a1..21d8861ef2 100644
--- a/src/lib/ecore/ecore_exe_posix.c
+++ b/src/lib/ecore/ecore_exe_posix.c
@@ -43,60 +43,51 @@
* appended with a preceding space. The first is the command off course.
*/
-struct _ecore_exe_dead_exe
-{
- pid_t pid;
- char *cmd;
-};
-
-static inline void _ecore_exe_exec_it(const char *exe_cmd,
+static inline void _ecore_exe_exec_it(const char *exe_cmd,
Ecore_Exe_Flags flags);
-static Eina_Bool _ecore_exe_data_generic_handler(void *data,
+static Eina_Bool _ecore_exe_data_generic_handler(void *data,
Ecore_Fd_Handler *fd_handler,
- Ecore_Exe_Flags flags);
-static Eina_Bool _ecore_exe_data_error_handler(void *data,
- Ecore_Fd_Handler *fd_handler);
-static Eina_Bool _ecore_exe_data_read_handler(void *data,
- Ecore_Fd_Handler *fd_handler);
-static Eina_Bool _ecore_exe_data_write_handler(void *data,
- Ecore_Fd_Handler *fd_handler);
-static void _ecore_exe_flush(Ecore_Exe *obj);
-static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid);
-static Eina_Bool _ecore_exe_make_sure_its_dead(void *data);
-static Eina_Bool _ecore_exe_make_sure_its_really_dead(void *data);
-static void _ecore_exe_dead_attach(Ecore_Exe *obj);
+ Ecore_Exe_Flags flags);
+static Eina_Bool _ecore_exe_data_error_handler(void *data,
+ Ecore_Fd_Handler *fd_handler);
+static Eina_Bool _ecore_exe_data_read_handler(void *data,
+ Ecore_Fd_Handler *fd_handler);
+static Eina_Bool _ecore_exe_data_write_handler(void *data,
+ Ecore_Fd_Handler *fd_handler);
+static void _ecore_exe_flush(Ecore_Exe *obj);
+static void _ecore_exe_make_sure_its_dead(void *data, const Efl_Event *event);
+static void _ecore_exe_make_sure_its_really_dead(void *data, const Efl_Event *event);
+static void _ecore_exe_dead_attach(Ecore_Exe *obj);
static const char *shell = NULL;
/* FIXME: This errno checking stuff should be put elsewhere for everybody to use.
* For now it lives here though, just to make testing easier.
*/
-static int _ecore_exe_check_errno(int result,
- const char *file,
- int line);
+static int _ecore_exe_check_errno(int result,
+ const char *file,
+ int line);
-#define E_IF_NO_ERRNO(result, foo, ok) \
- while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) \
- sleep(1); \
- if (ok)
+#define E_IF_NO_ERRNO(result, foo, ok) \
+ while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) sleep(1); \
+ if (ok)
-#define E_NO_ERRNO(result, foo, ok) \
- while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) \
- sleep(1)
+#define E_NO_ERRNO(result, foo, ok) \
+ while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) sleep(1)
#define E_IF_NO_ERRNO_NOLOOP(result, foo, ok) \
if (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)))
static int
-_ecore_exe_check_errno(int result,
+_ecore_exe_check_errno(int result,
const char *file EINA_UNUSED,
- int line EINA_UNUSED)
+ int line EINA_UNUSED)
{
int saved_errno = errno;
if (result == -1)
- {
- perror("*** errno reports ");
+ {
+ perror("*** errno reports ");
/* What is currently supported -
*
* pipe
@@ -152,63 +143,63 @@ _ecore_exe_check_errno(int result,
* // Something failed, cleanup.
* }
*/
- switch (saved_errno)
- {
- case EACCES:
- case EAGAIN:
- case EINTR:
- { /* Not now, try later. */
- ERR("*** Must try again in %s @%u.", file, line);
- result = -1;
- break;
- }
-
- case EMFILE:
- case ENFILE:
- case ENOLCK:
- { /* Low on resources. */
- ERR("*** Low on resources in %s @%u.", file,
- line);
- result = 0;
- break;
- }
-
- case EIO:
- { /* I/O error. */
- ERR("*** I/O error in %s @%u.", file, line);
- result = 0;
- break;
- }
-
- case EFAULT:
- case EBADF:
- case EINVAL:
- case EROFS:
- case EISDIR:
- case EDEADLK:
- case EPERM:
- case EBUSY:
- { /* Programmer fucked up. */
- ERR("*** NAUGHTY PROGRAMMER!!!\n"
- "*** SPANK SPANK SPANK!!!\n"
- "*** Now go fix your code in %s @%u. Tut tut tut!",
- file, line);
- result = 0;
- break;
- }
-
- default:
- { /* Unsupported errno code, please add this one. */
- ERR("*** NAUGHTY PROGRAMMER!!!\n"
- "*** SPANK SPANK SPANK!!!\n"
- "*** Unsupported errno code %d, please add this one.\n"
- "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!",
- saved_errno, __FILE__, __LINE__, file, line);
- result = 0;
- break;
- }
- }
- }
+ switch (saved_errno)
+ {
+ case EACCES:
+ case EAGAIN:
+ case EINTR:
+ { /* Not now, try later. */
+ ERR("*** Must try again in %s @%u.", file, line);
+ result = -1;
+ break;
+ }
+
+ case EMFILE:
+ case ENFILE:
+ case ENOLCK:
+ { /* Low on resources. */
+ ERR("*** Low on resources in %s @%u.", file,
+ line);
+ result = 0;
+ break;
+ }
+
+ case EIO:
+ { /* I/O error. */
+ ERR("*** I/O error in %s @%u.", file, line);
+ result = 0;
+ break;
+ }
+
+ case EFAULT:
+ case EBADF:
+ case EINVAL:
+ case EROFS:
+ case EISDIR:
+ case EDEADLK:
+ case EPERM:
+ case EBUSY:
+ { /* Programmer fucked up. */
+ ERR("*** NAUGHTY PROGRAMMER!!!\n"
+ "*** SPANK SPANK SPANK!!!\n"
+ "*** Now go fix your code in %s @%u. Tut tut tut!",
+ file, line);
+ result = 0;
+ break;
+ }
+
+ default:
+ { /* Unsupported errno code, please add this one. */
+ ERR("*** NAUGHTY PROGRAMMER!!!\n"
+ "*** SPANK SPANK SPANK!!!\n"
+ "*** Unsupported errno code %d, please add this one.\n"
+ "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!",
+ saved_errno, __FILE__, __LINE__, file, line);
+ result = 0;
+ break;
+ }
+ }
+ }
else /* Everything is fine. */
result = 1;
@@ -260,319 +251,327 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe)
/* Create some pipes. */
if (ok)
- {
- E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok)
- {
- }
- }
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok)
+ {
+ }
+ }
if (ok && (flags & ECORE_EXE_PIPE_ERROR))
- {
- E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok)
- {
- exe->child_fd_error = errorPipe[0];
- exe->child_fd_error_x = errorPipe[1];
- }
- }
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok)
+ {
+ exe->child_fd_error = errorPipe[0];
+ exe->child_fd_error_x = errorPipe[1];
+ }
+ }
if (ok && (flags & ECORE_EXE_PIPE_READ))
- {
- E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok)
- {
- exe->child_fd_read = readPipe[0];
- exe->child_fd_read_x = readPipe[1];
- }
- }
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok)
+ {
+ exe->child_fd_read = readPipe[0];
+ exe->child_fd_read_x = readPipe[1];
+ }
+ }
if (ok && (flags & ECORE_EXE_PIPE_WRITE))
- {
- E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok)
- {
- exe->child_fd_write = writePipe[1];
- exe->child_fd_write_x = writePipe[0];
- }
- }
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok)
+ {
+ exe->child_fd_write = writePipe[1];
+ exe->child_fd_write_x = writePipe[0];
+ }
+ }
if (ok)
- {
- pid_t pid = 0;
- volatile int vfork_exec_errno = 0;
-
- /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */
- /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */
- pid = fork();
-
- if (pid == -1)
- {
- ERR("Failed to fork process");
- pid = 0;
- }
- else if (pid == 0) /* child */
- {
+ {
+ pid_t pid = 0;
+ volatile int vfork_exec_errno = 0;
+
+ /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */
+ /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */
+ pid = fork();
+
+ if (pid == -1)
+ {
+ ERR("Failed to fork process");
+ pid = 0;
+ }
+ else if (pid == 0) /* child */
+ {
#ifdef HAVE_SYSTEMD
- unsetenv("NOTIFY_SOCKET");
+ unsetenv("NOTIFY_SOCKET");
#endif
- if (run_pri != ECORE_EXE_PRIORITY_INHERIT)
- {
-#ifdef PRIO_PROCESS
- if ((run_pri >= -20) && (run_pri <= 19))
- setpriority(PRIO_PROCESS, 0, run_pri);
+ if (run_pri != ECORE_EXE_PRIORITY_INHERIT)
+ {
+#ifdef PRIO_PROCESS
+ if ((run_pri >= -20) && (run_pri <= 19))
+ setpriority(PRIO_PROCESS, 0, run_pri);
#else
#warning "Your OS/libc does not provide PRIO_PROCESS (and possibly setpriority())"
#warning "This is a POSIX-1.2001 standard and it is highly encouraged that you"
#warning "Have support for this"
#endif
- }
- if (ok && (flags & ECORE_EXE_ISOLATE_IO))
- {
- int devnull;
-
- /* we want to isolatie the stdin/out/err of the process so
- * it can't share those of the parent, so close and replace with
- * /dev/null */
- devnull = open("/dev/null", O_RDONLY);
- if (devnull >= 0)
- {
- E_NO_ERRNO(result, close(STDIN_FILENO), ok);
- E_NO_ERRNO(result, dup2(devnull, STDIN_FILENO), ok);
- E_NO_ERRNO(result, close(devnull), ok);
- }
-
- devnull = open("/dev/null", O_WRONLY);
- if (devnull >= 0)
- {
- E_NO_ERRNO(result, close(STDOUT_FILENO), ok);
- E_NO_ERRNO(result, dup2(devnull, STDOUT_FILENO), ok);
- E_NO_ERRNO(result, close(devnull), ok);
- }
-
- devnull = open("/dev/null", O_WRONLY);
- if (devnull >= 0)
- {
- E_NO_ERRNO(result, close(STDERR_FILENO), ok);
- E_NO_ERRNO(result, dup2(devnull, STDERR_FILENO), ok);
- E_NO_ERRNO(result, close(devnull), ok);
- }
- }
- else
- {
- /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the
- * second pipe if it's open. On the other hand, there was the
- * Great FD Leak Scare of '06, so let's be paranoid. */
- if (ok && (flags & ECORE_EXE_PIPE_ERROR))
- {
- E_NO_ERRNO(result, close(STDERR_FILENO), ok);
- E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok);
- }
- if (ok && (flags & ECORE_EXE_PIPE_READ))
- {
- E_NO_ERRNO(result, close(STDOUT_FILENO), ok);
- E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok);
- }
- if (ok && (flags & ECORE_EXE_PIPE_WRITE))
- {
- E_NO_ERRNO(result, close(STDIN_FILENO), ok);
- E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok);
- }
- }
-
- if (ok)
- {
- /* Setup the status pipe. */
- E_NO_ERRNO(result, close(statusPipe[0]), ok);
- E_IF_NO_ERRNO(result, eina_file_close_on_exec(statusPipe[1], EINA_TRUE), ok) /* close on exec shows success */
- {
- /* Run the actual command. */
- _ecore_exe_exec_it(exe_cmd, flags); /* no return */
- }
- }
-
- /* Something went 'orribly wrong. */
- vfork_exec_errno = errno;
-
- /* Close the pipes. */
- if (flags & ECORE_EXE_PIPE_ERROR)
- E_NO_ERRNO(result, close(errorPipe[1]), ok);
- if (flags & ECORE_EXE_PIPE_READ)
- E_NO_ERRNO(result, close(readPipe[1]), ok);
- if (flags & ECORE_EXE_PIPE_WRITE)
- E_NO_ERRNO(result, close(writePipe[0]), ok);
- E_NO_ERRNO(result, close(statusPipe[1]), ok);
-
- _exit(-1);
- }
- else /* parent */
- {
- /* Close the unused pipes. */
- E_NO_ERRNO(result, close(statusPipe[1]), ok);
-
- /* FIXME: after having a good look at the current e fd
- * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */
- /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO
- * which is also linux specific so we probably don't want to
- * do this as long as select() is working fine. the only time
- * we really want to think of SIGIO async IO is when it all
- * actually works basically everywhere and we can turn all
- * IO into DMA async activities (i.e. you do a read() then
- * the read is complete not on return but when you get a
- * SIGIO - the read() just starts the transfer and it is
- * completed in the background by DMA (or whatever mechanism
- * the kernel choses)) */
-
- /* Wait for it to start executing. */
- /* FIXME: this doesn't seem very nice - we sit and block
- * waiting on a child process... even though it's just
- * the segment between the fork() and the exec) it just feels
- * wrong */
- for (;; )
- {
- char buf;
-
- E_NO_ERRNO(result, read(statusPipe[0], &buf, 1), ok);
- if (result == 0)
- {
- if (vfork_exec_errno != 0)
- {
- n = vfork_exec_errno;
- ERR("Could not start \"%s\"", exe_cmd);
- pid = 0;
- }
- break;
- }
- }
+ }
+ if (ok && (flags & ECORE_EXE_ISOLATE_IO))
+ {
+ int devnull;
+
+ /* we want to isolatie the stdin/out/err of the process so
+ * it can't share those of the parent, so close and replace with
+ * /dev/null */
+ devnull = open("/dev/null", O_RDONLY);
+ if (devnull >= 0)
+ {
+ E_NO_ERRNO(result, close(STDIN_FILENO), ok);
+ E_NO_ERRNO(result, dup2(devnull, STDIN_FILENO), ok);
+ E_NO_ERRNO(result, close(devnull), ok);
+ }
+
+ devnull = open("/dev/null", O_WRONLY);
+ if (devnull >= 0)
+ {
+ E_NO_ERRNO(result, close(STDOUT_FILENO), ok);
+ E_NO_ERRNO(result, dup2(devnull, STDOUT_FILENO), ok);
+ E_NO_ERRNO(result, close(devnull), ok);
+ }
+
+ devnull = open("/dev/null", O_WRONLY);
+ if (devnull >= 0)
+ {
+ E_NO_ERRNO(result, close(STDERR_FILENO), ok);
+ E_NO_ERRNO(result, dup2(devnull, STDERR_FILENO), ok);
+ E_NO_ERRNO(result, close(devnull), ok);
+ }
+ }
+ else
+ {
+ /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the
+ * second pipe if it's open. On the other hand, there was the
+ * Great FD Leak Scare of '06, so let's be paranoid. */
+ if (ok && (flags & ECORE_EXE_PIPE_ERROR))
+ {
+ E_NO_ERRNO(result, close(STDERR_FILENO), ok);
+ E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok);
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_READ))
+ {
+ E_NO_ERRNO(result, close(STDOUT_FILENO), ok);
+ E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok);
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_WRITE))
+ {
+ E_NO_ERRNO(result, close(STDIN_FILENO), ok);
+ E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok);
+ }
+ }
- /* Close the status pipe. */
+ if (ok)
+ {
+ /* Setup the status pipe. */
E_NO_ERRNO(result, close(statusPipe[0]), ok);
+ E_IF_NO_ERRNO(result, eina_file_close_on_exec(statusPipe[1], EINA_TRUE), ok) /* close on exec shows success */
+ {
+ /* Run the actual command. */
+ _ecore_exe_exec_it(exe_cmd, flags); /* no return */
+ }
+ }
+
+ /* Something went 'orribly wrong. */
+ vfork_exec_errno = errno;
+
+ /* Close the pipes. */
+ if (flags & ECORE_EXE_PIPE_ERROR)
+ E_NO_ERRNO(result, close(errorPipe[1]), ok);
+ if (flags & ECORE_EXE_PIPE_READ)
+ E_NO_ERRNO(result, close(readPipe[1]), ok);
+ if (flags & ECORE_EXE_PIPE_WRITE)
+ E_NO_ERRNO(result, close(writePipe[0]), ok);
+ E_NO_ERRNO(result, close(statusPipe[1]), ok);
+
+ _exit(-1);
+ }
+ else /* parent */
+ {
+ /* Close the unused pipes. */
+ E_NO_ERRNO(result, close(statusPipe[1]), ok);
+
+ /* FIXME: after having a good look at the current e fd
+ * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */
+ /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO
+ * which is also linux specific so we probably don't want to
+ * do this as long as select() is working fine. the only time
+ * we really want to think of SIGIO async IO is when it all
+ * actually works basically everywhere and we can turn all
+ * IO into DMA async activities (i.e. you do a read() then
+ * the read is complete not on return but when you get a
+ * SIGIO - the read() just starts the transfer and it is
+ * completed in the background by DMA (or whatever mechanism
+ * the kernel choses)) */
+
+ /* Wait for it to start executing. */
+ /* FIXME: this doesn't seem very nice - we sit and block
+ * waiting on a child process... even though it's just
+ * the segment between the fork() and the exec) it just feels
+ * wrong */
+ for (;; )
+ {
+ char buf;
+
+ E_NO_ERRNO(result, read(statusPipe[0], &buf, 1), ok);
+ if (result == 0)
+ {
+ if (vfork_exec_errno != 0)
+ {
+ n = vfork_exec_errno;
+ ERR("Could not start \"%s\"", exe_cmd);
+ pid = 0;
+ }
+ break;
+ }
}
- if (pid)
+ /* Close the status pipe. */
+ E_NO_ERRNO(result, close(statusPipe[0]), ok);
+ }
+
+ if (pid)
+ {
+ /* Setup the exe structure. */
+ exe->start_bytes = -1;
+ exe->end_bytes = -1;
+ exe->start_lines = -1;
+ exe->end_lines = -1;
+ exe->pid = pid;
+ exe->flags = flags;
+ if (exe->cmd)
{
- /* Setup the exe structure. */
- exe->start_bytes = -1;
- exe->end_bytes = -1;
- exe->start_lines = -1;
- exe->end_lines = -1;
- exe->pid = pid;
- exe->flags = flags;
- if (exe->cmd)
- {
- if (flags & ECORE_EXE_PIPE_ERROR) /* Setup the error stuff. */
- {
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_error, F_SETFL,
- O_NONBLOCK), ok) {
- }
- E_IF_NO_ERRNO(result,
- eina_file_close_on_exec(exe->child_fd_error, EINA_TRUE),
- ok) {
- }
- E_IF_NO_ERRNO(result,
- eina_file_close_on_exec(exe->child_fd_error_x, EINA_TRUE),
- ok) {
- }
- {
- exe->error_fd_handler =
- ecore_main_fd_handler_add(exe->child_fd_error,
- ECORE_FD_READ,
- _ecore_exe_data_error_handler,
- obj, NULL, NULL);
- if (!exe->error_fd_handler)
- ok = 0;
- }
- }
- if (ok && (flags & ECORE_EXE_PIPE_READ)) /* Setup the read stuff. */
- {
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_read, F_SETFL,
- O_NONBLOCK), ok) {
- }
- E_IF_NO_ERRNO(result,
- eina_file_close_on_exec(exe->child_fd_read, EINA_TRUE),
- ok) {
- }
- E_IF_NO_ERRNO(result,
- eina_file_close_on_exec(exe->child_fd_read_x, EINA_TRUE),
- ok) {
- }
- {
- exe->read_fd_handler =
- ecore_main_fd_handler_add(exe->child_fd_read,
- ECORE_FD_READ,
- _ecore_exe_data_read_handler,
- obj, NULL, NULL);
- if (!exe->read_fd_handler)
- ok = 0;
- }
- }
- if (ok && (flags & ECORE_EXE_PIPE_WRITE)) /* Setup the write stuff. */
- {
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_write, F_SETFL,
- O_NONBLOCK), ok) {
- }
- E_IF_NO_ERRNO(result,
- eina_file_close_on_exec(exe->child_fd_write, EINA_TRUE),
- ok) {
- }
- E_IF_NO_ERRNO(result,
- eina_file_close_on_exec(exe->child_fd_write_x, EINA_TRUE),
- ok) {
- }
- {
- exe->write_fd_handler =
- ecore_main_fd_handler_add(exe->child_fd_write,
- ECORE_FD_WRITE,
- _ecore_exe_data_write_handler,
- obj, NULL, NULL);
- if (exe->write_fd_handler)
- ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */
- else
- ok = 0;
- }
- }
-
- _ecore_exe_exes = eina_list_append(_ecore_exe_exes, obj);
- n = 0;
- }
- else
- ok = 0;
+ if (flags & ECORE_EXE_PIPE_ERROR) /* Setup the error stuff. */
+ {
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_error, F_SETFL,
+ O_NONBLOCK), ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ eina_file_close_on_exec(exe->child_fd_error, EINA_TRUE),
+ ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ eina_file_close_on_exec(exe->child_fd_error_x, EINA_TRUE),
+ ok) {
+ }
+ {
+ // XXX: eoify ecore fd handlers
+ exe->error_fd_handler =
+ ecore_main_fd_handler_add(exe->child_fd_error,
+ ECORE_FD_READ,
+ _ecore_exe_data_error_handler,
+ obj, NULL, NULL);
+ if (!exe->error_fd_handler)
+ ok = 0;
+ }
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_READ)) /* Setup the read stuff. */
+ {
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_read, F_SETFL,
+ O_NONBLOCK), ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ eina_file_close_on_exec(exe->child_fd_read, EINA_TRUE),
+ ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ eina_file_close_on_exec(exe->child_fd_read_x, EINA_TRUE),
+ ok) {
+ }
+ {
+ // XXX: eoify ecore fd handlers
+ exe->read_fd_handler =
+ ecore_main_fd_handler_add(exe->child_fd_read,
+ ECORE_FD_READ,
+ _ecore_exe_data_read_handler,
+ obj, NULL, NULL);
+ if (!exe->read_fd_handler)
+ ok = 0;
+ }
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_WRITE)) /* Setup the write stuff. */
+ {
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_write, F_SETFL,
+ O_NONBLOCK), ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ eina_file_close_on_exec(exe->child_fd_write, EINA_TRUE),
+ ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ eina_file_close_on_exec(exe->child_fd_write_x, EINA_TRUE),
+ ok) {
+ }
+ {
+ // XXX: eoify ecore fd handlers
+ exe->write_fd_handler =
+ ecore_main_fd_handler_add(exe->child_fd_write,
+ ECORE_FD_WRITE,
+ _ecore_exe_data_write_handler,
+ obj, NULL, NULL);
+ // XXX: eoify ecore fd handlers
+ if (exe->write_fd_handler)
+ ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */
+ else
+ ok = 0;
+ }
+ }
+
+ exe->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
+ Efl_Loop_Data *loop = efl_data_scope_get(exe->loop, EFL_LOOP_CLASS);
+ if (loop) loop->exes = eina_list_append(loop->exes, obj);
+ n = 0;
}
- else
- ok = 0;
- }
+ else
+ ok = 0;
+ }
+ else
+ ok = 0;
+ }
if (!ok) /* Something went wrong, so pull down everything. */
- {
- if (exe->pid) ecore_exe_terminate(obj);
- obj = NULL;
- }
+ {
+ // XXX: eoify terminate method
+ if (exe->pid) ecore_exe_terminate(obj);
+ obj = NULL;
+ }
else
- {
- Ecore_Exe_Event_Add *e;
+ {
+ Ecore_Exe_Event_Add *e;
- e = _ecore_exe_event_add_new();
- if (e)
- {
- e->exe = obj;
- /* Send the event. */
- ecore_event_add(ECORE_EXE_EVENT_ADD, e,
- _ecore_exe_event_add_free, NULL);
- }
- /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */
- }
+ e = _ecore_exe_event_add_new();
+ if (e)
+ {
+ e->exe = obj;
+ // XXX: eoify ecore_event_add
+ /* Send the event. */
+ ecore_event_add(ECORE_EXE_EVENT_ADD, e,
+ _ecore_exe_event_add_free, NULL);
+ }
+ /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */
+ }
errno = n;
return obj;
}
Eina_Bool
-_impl_ecore_exe_send(Ecore_Exe *obj EINA_UNUSED,
- Ecore_Exe_Data *exe,
- const void *data,
- int size)
+_impl_ecore_exe_send(Ecore_Exe *obj EINA_UNUSED,
+ Ecore_Exe_Data *exe,
+ const void *data,
+ int size)
{
void *buf;
if (exe->child_fd_write == -1)
{
ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! "
- "Cannot send %d bytes from %p", exe, size, data);
+ "Cannot send %d bytes from %p", exe, size, data);
return EINA_FALSE;
}
@@ -583,19 +582,20 @@ _impl_ecore_exe_send(Ecore_Exe *obj EINA_UNUSED,
memcpy((char *)exe->write_data_buf + exe->write_data_size, data, size);
exe->write_data_size += size;
+ // XXX: eoify ecore_fd_handlers
if (exe->write_fd_handler)
- ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE);
+ ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE);
return EINA_TRUE;
}
void
_impl_ecore_exe_auto_limits_set(Ecore_Exe *obj EINA_UNUSED,
- Ecore_Exe_Data *exe,
- int start_bytes,
- int end_bytes,
- int start_lines,
- int end_lines)
+ Ecore_Exe_Data *exe,
+ int start_bytes,
+ int end_bytes,
+ int start_lines,
+ int end_lines)
{
/* FIXME: sanitize the input. */
exe->start_bytes = start_bytes;
@@ -644,9 +644,9 @@ _impl_ecore_exe_auto_limits_set(Ecore_Exe *obj EINA_UNUSED,
}
Ecore_Exe_Event_Data *
-_impl_ecore_exe_event_data_get(Ecore_Exe *obj,
- Ecore_Exe_Data *exe,
- Ecore_Exe_Flags flags)
+_impl_ecore_exe_event_data_get(Ecore_Exe *obj,
+ Ecore_Exe_Data *exe,
+ Ecore_Exe_Flags flags)
{
Ecore_Exe_Event_Data *e = NULL;
int is_buffered = 0;
@@ -655,130 +655,130 @@ _impl_ecore_exe_event_data_get(Ecore_Exe *obj,
/* Sort out what sort of event we are. */
if (flags & ECORE_EXE_PIPE_READ)
- {
- flags = ECORE_EXE_PIPE_READ;
- if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED)
- is_buffered = 1;
- }
+ {
+ flags = ECORE_EXE_PIPE_READ;
+ if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED)
+ is_buffered = 1;
+ }
else
- {
- flags = ECORE_EXE_PIPE_ERROR;
- if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED)
- is_buffered = 1;
- }
+ {
+ flags = ECORE_EXE_PIPE_ERROR;
+ if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED)
+ is_buffered = 1;
+ }
/* Get the data. */
if (flags & ECORE_EXE_PIPE_READ)
- {
- inbuf = exe->read_data_buf;
- inbuf_num = exe->read_data_size;
- exe->read_data_buf = NULL;
- exe->read_data_size = 0;
- }
+ {
+ inbuf = exe->read_data_buf;
+ inbuf_num = exe->read_data_size;
+ exe->read_data_buf = NULL;
+ exe->read_data_size = 0;
+ }
else
- {
- inbuf = exe->error_data_buf;
- inbuf_num = exe->error_data_size;
- exe->error_data_buf = NULL;
- exe->error_data_size = 0;
- }
+ {
+ inbuf = exe->error_data_buf;
+ inbuf_num = exe->error_data_size;
+ exe->error_data_buf = NULL;
+ exe->error_data_size = 0;
+ }
e = calloc(1, sizeof(Ecore_Exe_Event_Data));
if (e)
- {
- e->exe = obj;
- e->data = inbuf;
- e->size = inbuf_num;
-
- if (is_buffered) /* Deal with line buffering. */
- {
- int max = 0;
- int count = 0;
- int i;
- int last = 0;
- char *c;
-
- c = (char *)inbuf;
- for (i = 0; i < inbuf_num; i++) /* Find the lines. */
- {
- if (inbuf[i] == '\n')
- {
- if (count >= max)
- {
- Ecore_Exe_Event_Data_Line *lines;
-
- /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */
- max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */
- lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */
- if (!lines)
- {
- ERR("Out of memory adding exe data lines to event");
- break;
- }
- e->lines = lines;
- }
- /* raster said to leave the line endings as line endings, however -
- * This is line buffered mode, we are not dealing with binary here, but lines.
- * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format.
- * Thus the user is most likely gonna deal with this text as strings.
- * Thus the user is most likely gonna pass this data to str functions.
- * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0'
- * We are handing them the string length as a convenience.
- * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough.
- * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer.
- * Let's make it easy on them to use these as standard C strings.
- *
- * onefang is proud to announce that he has just set a new personal record for the
- * most over documentation of a simple assignment statement. B-)
- */
- inbuf[i] = '\0';
- e->lines[count].line = c;
- e->lines[count].size = i - last;
- last = i + 1;
- c = (char *)&inbuf[last];
- count++;
- }
- }
- if (i > last) /* Partial line left over, save it for next time. */
- {
- if (count != 0) e->size = last;
- if (flags & ECORE_EXE_PIPE_READ)
- {
- exe->read_data_size = i - last;
- exe->read_data_buf = malloc(exe->read_data_size);
- if (exe->read_data_buf)
- memcpy(exe->read_data_buf, c, exe->read_data_size);
- else
- {
- exe->read_data_size = 0;
- ERR("Out of memory in allocating exe pipe data");
- }
- }
- else
- {
- exe->error_data_size = i - last;
- exe->error_data_buf = malloc(exe->error_data_size);
- if (exe->error_data_buf)
- memcpy(exe->error_data_buf, c, exe->error_data_size);
- else
- {
- exe->error_data_size = 0;
- ERR("Out of memory in allocating exe pipe data");
- }
- }
- }
- if (count == 0) /* No lines to send, cancel the event. */
- {
- _ecore_exe_event_exe_data_free(NULL, e);
- e = NULL;
- }
- else /* NULL terminate the array, so that people know where the end is. */
+ {
+ e->exe = obj;
+ e->data = inbuf;
+ e->size = inbuf_num;
+
+ if (is_buffered) /* Deal with line buffering. */
+ {
+ int max = 0;
+ int count = 0;
+ int i;
+ int last = 0;
+ char *c;
+
+ c = (char *)inbuf;
+ for (i = 0; i < inbuf_num; i++) /* Find the lines. */
+ {
+ if (inbuf[i] == '\n')
+ {
+ if (count >= max)
{
- e->lines[count].line = NULL;
- e->lines[count].size = 0;
+ Ecore_Exe_Event_Data_Line *lines;
+
+ /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */
+ max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */
+ lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */
+ if (!lines)
+ {
+ ERR("Out of memory adding exe data lines to event");
+ break;
+ }
+ e->lines = lines;
}
- }
- }
+ /* raster said to leave the line endings as line endings, however -
+ * This is line buffered mode, we are not dealing with binary here, but lines.
+ * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format.
+ * Thus the user is most likely gonna deal with this text as strings.
+ * Thus the user is most likely gonna pass this data to str functions.
+ * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0'
+ * We are handing them the string length as a convenience.
+ * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough.
+ * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer.
+ * Let's make it easy on them to use these as standard C strings.
+ *
+ * onefang is proud to announce that he has just set a new personal record for the
+ * most over documentation of a simple assignment statement. B-)
+ */
+ inbuf[i] = '\0';
+ e->lines[count].line = c;
+ e->lines[count].size = i - last;
+ last = i + 1;
+ c = (char *)&inbuf[last];
+ count++;
+ }
+ }
+ if (i > last) /* Partial line left over, save it for next time. */
+ {
+ if (count != 0) e->size = last;
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ exe->read_data_size = i - last;
+ exe->read_data_buf = malloc(exe->read_data_size);
+ if (exe->read_data_buf)
+ memcpy(exe->read_data_buf, c, exe->read_data_size);
+ else
+ {
+ exe->read_data_size = 0;
+ ERR("Out of memory in allocating exe pipe data");
+ }
+ }
+ else
+ {
+ exe->error_data_size = i - last;
+ exe->error_data_buf = malloc(exe->error_data_size);
+ if (exe->error_data_buf)
+ memcpy(exe->error_data_buf, c, exe->error_data_size);
+ else
+ {
+ exe->error_data_size = 0;
+ ERR("Out of memory in allocating exe pipe data");
+ }
+ }
+ }
+ if (count == 0) /* No lines to send, cancel the event. */
+ {
+ _ecore_exe_event_exe_data_free(NULL, e);
+ e = NULL;
+ }
+ else /* NULL terminate the array, so that people know where the end is. */
+ {
+ e->lines[count].line = NULL;
+ e->lines[count].size = 0;
+ }
+ }
+ }
return e;
}
@@ -795,20 +795,9 @@ _impl_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe)
if (exe->pre_free_cb)
exe->pre_free_cb(data, obj);
- if (exe->doomsday_clock)
- {
- struct _ecore_exe_dead_exe *dead;
+ exe->doomsday_clock = NULL;
- ecore_timer_del(exe->doomsday_clock);
- exe->doomsday_clock = NULL;
- dead = exe->doomsday_clock_dead;
- if (dead)
- {
- IF_FREE(dead->cmd);
- free(dead);
- exe->doomsday_clock_dead = NULL;
- }
- }
+ // XXX: eoify ecore fd handlers
IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler);
IF_FN_DEL(ecore_main_fd_handler_del, exe->read_fd_handler);
IF_FN_DEL(ecore_main_fd_handler_del, exe->error_fd_handler);
@@ -829,7 +818,8 @@ _impl_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe)
IF_FREE(exe->error_data_buf);
IF_FREE(exe->cmd);
- _ecore_exe_exes = eina_list_remove(_ecore_exe_exes, obj);
+ Efl_Loop_Data *loop = efl_data_scope_get(exe->loop, EFL_LOOP_CLASS);
+ if (loop) loop->exes = eina_list_remove(loop->exes, obj);
IF_FREE(exe->tag);
}
@@ -870,25 +860,21 @@ _impl_ecore_exe_terminate(Ecore_Exe *obj, Ecore_Exe_Data *exe)
void
_impl_ecore_exe_kill(Ecore_Exe *obj EINA_UNUSED, Ecore_Exe_Data *exe)
{
- struct _ecore_exe_dead_exe *dead;
- dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
- if (dead)
- {
- dead->pid = exe->pid;
- dead->cmd = strdup(exe->cmd);
- IF_FN_DEL(ecore_timer_del, exe->doomsday_clock);
- exe->doomsday_clock =
- ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
- }
-
+ efl_del(exe->doomsday_clock);
+ exe->doomsday_clock = efl_add(EFL_LOOP_TIMER_CLASS, obj,
+ efl_event_callback_add(efl_added,
+ EFL_LOOP_TIMER_EVENT_TICK,
+ _ecore_exe_make_sure_its_really_dead,
+ obj),
+ efl_loop_timer_interval_set(efl_added, 10.0));
INF("Sending KILL signal to %s (%d).", exe->cmd, exe->pid);
kill(exe->pid, SIGKILL);
}
void
_impl_ecore_exe_signal(Ecore_Exe *obj EINA_UNUSED,
- Ecore_Exe_Data *exe,
- int num)
+ Ecore_Exe_Data *exe,
+ int num)
{
if (num == 1)
kill(exe->pid, SIGUSR1);
@@ -902,102 +888,41 @@ _impl_ecore_exe_hup(Ecore_Exe *obj EINA_UNUSED, Ecore_Exe_Data *exe)
kill(exe->pid, SIGHUP);
}
-static Ecore_Exe *
-_ecore_exe_is_it_alive(pid_t pid)
-{
- Ecore_Exe *exe = NULL;
-
- /* FIXME: There is no nice, safe, OS independent way to tell if a
- * particular PID is still alive. I have written code to do so
- * for my urunlevel busybox applet (http://urunlevel.sourceforge.net/),
- * but it's for linux only, and still not guaranteed.
- *
- * So for now, we just check that a valid Ecore_Exe structure
- * exists for it. Even that is not a guarantee, as the structure
- * can be freed without killing the process.
- *
- * I think we can safely put exe's into two categories, those users
- * that care about the life of the exe, and the run and forget type.
- * The run and forget type starts up the exe, then free's the
- * Ecore_Exe structure straight away. They can never call any of
- * the functions that can call this, so we don't worry about them.
- *
- * Those user's that care about the life of exe's will keep the
- * Ecore_Exe structure around, terminate them eventually, or
- * register for exit events. For these ones the assumption
- * that valid Ecore_Exe struct == live exe is almost valid.
- *
- * I will probably copy my urunlevel code into here someday.
- */
- exe = _ecore_exe_find(pid);
-
- return exe;
-}
-
-static Eina_Bool
-_ecore_exe_make_sure_its_dead(void *data)
+static void
+_ecore_exe_make_sure_its_dead(void *data, const Efl_Event *event EINA_UNUSED)
{
- struct _ecore_exe_dead_exe *dead;
-
- dead = data;
- if (dead)
+ Eo *exe_obj = data;
+ Ecore_Exe_Data *exe = efl_data_scope_get(exe_obj, MY_CLASS);
+ if (exe)
{
- Ecore_Exe *obj = NULL;
-
- if ((obj = _ecore_exe_is_it_alive(dead->pid)))
- {
- Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
- if (exe)
- {
- if (dead->cmd)
- INF("Sending KILL signal to allegedly dead %s (%d).",
- dead->cmd, dead->pid);
- else
- INF("Sending KILL signal to allegedly dead PID %d.",
- dead->pid);
- exe->doomsday_clock =
- ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead,
- dead);
- kill(dead->pid, SIGKILL);
- }
- }
+ if (exe->cmd)
+ INF("Sending KILL signal to allegedly dead %s (%d).", exe->cmd, exe->pid);
else
- {
- IF_FREE(dead->cmd);
- free(dead);
- }
+ INF("Sending KILL signal to allegedly dead PID %d.", exe->pid);
+ exe->doomsday_clock = efl_add(EFL_LOOP_TIMER_CLASS, exe_obj,
+ efl_event_callback_add(efl_added,
+ EFL_LOOP_TIMER_EVENT_TICK,
+ _ecore_exe_make_sure_its_really_dead,
+ exe_obj),
+ efl_loop_timer_interval_set(efl_added, 10.0));
+ kill(exe->pid, SIGKILL);
}
- return ECORE_CALLBACK_CANCEL;
}
-static Eina_Bool
-_ecore_exe_make_sure_its_really_dead(void *data)
+static void
+_ecore_exe_make_sure_its_really_dead(void *data, const Efl_Event *event EINA_UNUSED)
{
- struct _ecore_exe_dead_exe *dead;
-
- dead = data;
- if (dead)
+ Eo *exe_obj = data;
+ Ecore_Exe_Data *exe = efl_data_scope_get(exe_obj, MY_CLASS);
+ if (exe)
{
- Ecore_Exe *obj = NULL;
-
- if ((obj = _ecore_exe_is_it_alive(dead->pid)))
- {
- Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
-
- if (exe)
- {
- ERR("RUN! The zombie wants to eat your brains! And your CPU!");
- if (dead->cmd)
- INF("%s (%d) is not really dead.", dead->cmd, dead->pid);
- else
- INF("PID %d is not really dead.", dead->pid);
- exe->doomsday_clock = NULL;
- }
- IF_FREE(dead->cmd);
- free(dead);
- }
+ ERR("RUN! The zombie wants to eat your brains! And your CPU!");
+ if (exe->cmd)
+ INF("%s (%d) is not really dead.", exe->cmd, exe->pid);
+ else
+ INF("PID %d is not really dead.", exe->pid);
+ exe->doomsday_clock = NULL;
}
- return ECORE_CALLBACK_CANCEL;
}
Ecore_Timer *
@@ -1009,7 +934,7 @@ _ecore_exe_doomsday_clock_get(Ecore_Exe *obj)
}
void
-_ecore_exe_doomsday_clock_set(Ecore_Exe *obj,
+_ecore_exe_doomsday_clock_set(Ecore_Exe *obj,
Ecore_Timer *dc)
{
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
@@ -1018,7 +943,7 @@ _ecore_exe_doomsday_clock_set(Ecore_Exe *obj,
}
static inline void
-_ecore_exe_exec_it(const char *exe_cmd,
+_ecore_exe_exec_it(const char *exe_cmd,
Ecore_Exe_Flags flags)
{
char use_sh = 1;
@@ -1033,55 +958,55 @@ _ecore_exe_exec_it(const char *exe_cmd,
* If we don't find them, we can call the exe directly.
*/
if (!strpbrk(exe_cmd, "|&;<>()$`\\\"'*?#"))
- {
- char *token;
- char pre_command = 1;
- int num_tokens = 0;
- int len;
-
- len = strlen(exe_cmd);
- buf = alloca(len + 1);
- strcpy(buf, exe_cmd);
- buf[len] = 0;
-
- token = strtok(buf, " \t\n\v");
- while (token)
- {
- if (token[0] == '~')
- break;
- if (pre_command)
- {
- if (token[0] == '[')
- break;
- if (strchr(token, '='))
- break;
- else
- pre_command = 0;
- }
- num_tokens++;
- token = strtok(NULL, " \t\n\v");
- }
- if ((!token) && (num_tokens))
- {
- int i = 0;
-
- len = strlen(exe_cmd);
- buf = alloca(len + 1);
- strcpy(buf, exe_cmd);
- buf[len] = 0;
-
- token = strtok(buf, " \t\n\v");
- use_sh = 0;
- args = alloca((num_tokens + 1) * sizeof(char *));
- for (i = 0; i < num_tokens; i++)
- {
- if (token)
- args[i] = token;
- token = strtok(NULL, " \t\n\v");
- }
- args[num_tokens] = NULL;
- }
- }
+ {
+ char *token;
+ char pre_command = 1;
+ int num_tokens = 0;
+ int len;
+
+ len = strlen(exe_cmd);
+ buf = alloca(len + 1);
+ strcpy(buf, exe_cmd);
+ buf[len] = 0;
+
+ token = strtok(buf, " \t\n\v");
+ while (token)
+ {
+ if (token[0] == '~')
+ break;
+ if (pre_command)
+ {
+ if (token[0] == '[')
+ break;
+ if (strchr(token, '='))
+ break;
+ else
+ pre_command = 0;
+ }
+ num_tokens++;
+ token = strtok(NULL, " \t\n\v");
+ }
+ if ((!token) && (num_tokens))
+ {
+ int i = 0;
+
+ len = strlen(exe_cmd);
+ buf = alloca(len + 1);
+ strcpy(buf, exe_cmd);
+ buf[len] = 0;
+
+ token = strtok(buf, " \t\n\v");
+ use_sh = 0;
+ args = alloca((num_tokens + 1) * sizeof(char *));
+ for (i = 0; i < num_tokens; i++)
+ {
+ if (token)
+ args[i] = token;
+ token = strtok(NULL, " \t\n\v");
+ }
+ args[num_tokens] = NULL;
+ }
+ }
#ifdef HAVE_PRCTL
if ((flags & ECORE_EXE_TERM_WITH_PARENT))
@@ -1092,34 +1017,34 @@ _ecore_exe_exec_it(const char *exe_cmd,
if (!(flags & ECORE_EXE_NOT_LEADER)) setsid();
if ((flags & ECORE_EXE_USE_SH))
- {
- errno = 0;
- execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL);
- }
+ {
+ errno = 0;
+ execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL);
+ }
else if (use_sh) /* We have to use a shell to run this. */
- {
- if (!shell) /* Find users preferred shell. */
- {
+ {
+ if (!shell) /* Find users preferred shell. */
+ {
#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
- if (getuid() == geteuid())
+ if (getuid() == geteuid())
#endif
- shell = getenv("SHELL");
- if (!shell)
- shell = "/bin/sh";
- }
- errno = 0;
- execl(shell, shell, "-c", exe_cmd, (char *)NULL);
- }
- else /* We can run this directly. */
- {
- if (!args)
- {
- ERR("arg[0] is NULL!");
- return;
- }
- errno = 0;
- if (args[0]) execvp(args[0], args);
- }
+ shell = getenv("SHELL");
+ if (!shell)
+ shell = "/bin/sh";
+ }
+ errno = 0;
+ execl(shell, shell, "-c", exe_cmd, (char *)NULL);
+ }
+ else
+ { /* We can run this directly. */
+ if (!args)
+ {
+ ERR("arg[0] is NULL!");
+ return;
+ }
+ errno = 0;
+ if (args[0]) execvp(args[0], args);
+ }
save_errno = errno;
errno = save_errno;
@@ -1127,9 +1052,9 @@ _ecore_exe_exec_it(const char *exe_cmd,
}
static Eina_Bool
-_ecore_exe_data_generic_handler(void *data,
+_ecore_exe_data_generic_handler(void *data,
Ecore_Fd_Handler *fd_handler,
- Ecore_Exe_Flags flags)
+ Ecore_Exe_Flags flags)
{
Ecore_Exe *obj = data;
int child_fd;
@@ -1141,139 +1066,142 @@ _ecore_exe_data_generic_handler(void *data,
/* Sort out what sort of handler we are. */
if (flags & ECORE_EXE_PIPE_READ)
- {
- flags = ECORE_EXE_PIPE_READ;
- event_type = ECORE_EXE_EVENT_DATA;
- eo_event = ECORE_EXE_EVENT_DATA_GET;
- child_fd = exe->child_fd_read;
- }
+ {
+ flags = ECORE_EXE_PIPE_READ;
+ event_type = ECORE_EXE_EVENT_DATA;
+ eo_event = ECORE_EXE_EVENT_DATA_GET;
+ child_fd = exe->child_fd_read;
+ }
else
- {
- flags = ECORE_EXE_PIPE_ERROR;
- event_type = ECORE_EXE_EVENT_ERROR;
- eo_event = ECORE_EXE_EVENT_DATA_ERROR;
- child_fd = exe->child_fd_error;
- }
+ {
+ flags = ECORE_EXE_PIPE_ERROR;
+ event_type = ECORE_EXE_EVENT_ERROR;
+ eo_event = ECORE_EXE_EVENT_DATA_ERROR;
+ child_fd = exe->child_fd_error;
+ }
if ((fd_handler)
&& (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)))
- {
- unsigned char *inbuf, *temp;
- int inbuf_num;
-
- /* Get any left over data from last time. */
- if (flags & ECORE_EXE_PIPE_READ)
- {
- inbuf = exe->read_data_buf;
- inbuf_num = exe->read_data_size;
- exe->read_data_buf = NULL;
- exe->read_data_size = 0;
- }
- else
- {
- inbuf = exe->error_data_buf;
- inbuf_num = exe->error_data_size;
- exe->error_data_buf = NULL;
- exe->error_data_size = 0;
- }
-
- for (;; )
- {
- int num, lost_exe;
- char buf[READBUFSIZ];
-
- lost_exe = 0;
- errno = 0;
- if ((num = read(child_fd, buf, READBUFSIZ)) < 1)
+ {
+ unsigned char *inbuf, *temp;
+ int inbuf_num;
+
+ /* Get any left over data from last time. */
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ inbuf = exe->read_data_buf;
+ inbuf_num = exe->read_data_size;
+ exe->read_data_buf = NULL;
+ exe->read_data_size = 0;
+ }
+ else
+ {
+ inbuf = exe->error_data_buf;
+ inbuf_num = exe->error_data_size;
+ exe->error_data_buf = NULL;
+ exe->error_data_size = 0;
+ }
+
+ for (;; )
+ {
+ int num, lost_exe;
+ char buf[READBUFSIZ];
+
+ lost_exe = 0;
+ errno = 0;
+ if ((num = read(child_fd, buf, READBUFSIZ)) < 1)
+ {
+ /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE
+ * (currently 64k) to inbuf, use that instead of buf, and
+ * save ourselves a memcpy(). */
+ lost_exe = ((errno == EIO) ||
+ (errno == EBADF) ||
+ (errno == EPIPE) ||
+ (errno == EINVAL) || (errno == ENOSPC));
+ if ((errno != EAGAIN) && (errno != EINTR))
+ perror("_ecore_exe_generic_handler() read problem ");
+ }
+ if (num > 0) /* data got read. */
+ {
+ temp = inbuf;
+ inbuf = realloc(inbuf, inbuf_num + num);
+ if (inbuf)
+ {
+ memcpy(inbuf + inbuf_num, buf, num);
+ inbuf_num += num;
+ }
+ else // realloc fails and returns NULL.
+ {
+ ERR("Out of memory in exe generic data handler");
+ inbuf = temp;
+ }
+ }
+ else
+ { /* No more data to read. */
+ if (inbuf)
+ {
+ Ecore_Exe_Event_Data *e;
+
+ /* Stash the data away for later. */
+ if (flags & ECORE_EXE_PIPE_READ)
{
- /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE
- * (currently 64k) to inbuf, use that instead of buf, and
- * save ourselves a memcpy(). */
- lost_exe = ((errno == EIO) ||
- (errno == EBADF) ||
- (errno == EPIPE) ||
- (errno == EINVAL) || (errno == ENOSPC));
- if ((errno != EAGAIN) && (errno != EINTR))
- perror("_ecore_exe_generic_handler() read problem ");
+ exe->read_data_buf = inbuf;
+ exe->read_data_size = inbuf_num;
}
- if (num > 0) /* data got read. */
+ else
{
- temp = inbuf;
- inbuf = realloc(inbuf, inbuf_num + num);
- if (inbuf)
- {
- memcpy(inbuf + inbuf_num, buf, num);
- inbuf_num += num;
- }
- else // realloc fails and returns NULL.
- {
- ERR("Out of memory in exe generic data handler");
- inbuf = temp;
- }
+ exe->error_data_buf = inbuf;
+ exe->error_data_size = inbuf_num;
}
- else /* No more data to read. */
+
+ if (!(exe->flags & ECORE_EXE_PIPE_AUTO))
{
- if (inbuf)
- {
- Ecore_Exe_Event_Data *e;
-
- /* Stash the data away for later. */
- if (flags & ECORE_EXE_PIPE_READ)
- {
- exe->read_data_buf = inbuf;
- exe->read_data_size = inbuf_num;
- }
- else
- {
- exe->error_data_buf = inbuf;
- exe->error_data_size = inbuf_num;
- }
-
- if (!(exe->flags & ECORE_EXE_PIPE_AUTO))
- {
- e = ecore_exe_event_data_get(obj, flags);
- if (e) /* Send the event. */
- {
- ecore_event_add(event_type, e,
- _ecore_exe_event_exe_data_free,
- NULL);
- efl_event_callback_call(obj, eo_event, e);
- }
- }
- }
- if (lost_exe)
+ // XXX: use eo method
+ e = ecore_exe_event_data_get(obj, flags);
+ if (e) /* Send the event. */
{
- if (flags & ECORE_EXE_PIPE_READ)
- {
- if (exe->read_data_size)
- INF("There are %d bytes left unsent from the dead exe %s.",
- exe->read_data_size, exe->cmd);
- }
- else
- {
- if (exe->error_data_size)
- INF("There are %d bytes left unsent from the dead exe %s.",
- exe->error_data_size, exe->cmd);
- }
- /* Thought about this a bit. If the exe has actually
- * died, this won't do any harm as it must have died
- * recently and the pid has not had a chance to recycle.
- * It is also a paranoid catchall, coz the usual ecore_signal
- * mechanism should kick in. But let's give it a good
- * kick in the head anyway.
- */
- ecore_exe_terminate(obj);
+ // XXX: eoify ecore event
+ ecore_event_add(event_type, e,
+ _ecore_exe_event_exe_data_free,
+ NULL);
+ efl_event_callback_call(obj, eo_event, e);
}
- break;
}
- }
- }
+ }
+ if (lost_exe)
+ {
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ if (exe->read_data_size)
+ INF("There are %d bytes left unsent from the dead exe %s.",
+ exe->read_data_size, exe->cmd);
+ }
+ else
+ {
+ if (exe->error_data_size)
+ INF("There are %d bytes left unsent from the dead exe %s.",
+ exe->error_data_size, exe->cmd);
+ }
+ /* Thought about this a bit. If the exe has actually
+ * died, this won't do any harm as it must have died
+ * recently and the pid has not had a chance to recycle.
+ * It is also a paranoid catchall, coz the usual ecore_signal
+ * mechanism should kick in. But let's give it a good
+ * kick in the head anyway.
+ */
+ // XXX: use eo method
+ ecore_exe_terminate(obj);
+ }
+ break;
+ }
+ }
+ }
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
-_ecore_exe_data_error_handler(void *data,
+_ecore_exe_data_error_handler(void *data,
Ecore_Fd_Handler *fd_handler)
{
return _ecore_exe_data_generic_handler(data, fd_handler,
@@ -1281,7 +1209,7 @@ _ecore_exe_data_error_handler(void *data,
}
static Eina_Bool
-_ecore_exe_data_read_handler(void *data,
+_ecore_exe_data_read_handler(void *data,
Ecore_Fd_Handler *fd_handler)
{
return _ecore_exe_data_generic_handler(data, fd_handler,
@@ -1289,7 +1217,7 @@ _ecore_exe_data_read_handler(void *data,
}
static Eina_Bool
-_ecore_exe_data_write_handler(void *data,
+_ecore_exe_data_write_handler(void *data,
Ecore_Fd_Handler *fd_handler EINA_UNUSED)
{
Ecore_Exe *obj = data;
@@ -1297,9 +1225,10 @@ _ecore_exe_data_write_handler(void *data,
if (!exe) return EINA_FALSE;
+ // XXX: use eo method
if ((exe->write_fd_handler) &&
(ecore_main_fd_handler_active_get
- (exe->write_fd_handler, ECORE_FD_WRITE)))
+ (exe->write_fd_handler, ECORE_FD_WRITE)))
_ecore_exe_flush(obj);
/* If we have sent all there is to send, and we need to close the pipe, then close it. */
@@ -1339,7 +1268,9 @@ _ecore_exe_flush(Ecore_Exe *obj)
{
if (errno == EIO || errno == EBADF || errno == EPIPE || errno == EINVAL || errno == ENOSPC) /* we lost our exe! */
{
+ // XXX: use eo method (eoify)
ecore_exe_terminate(obj);
+ // XXX: eoify fd handlers
if (exe->write_fd_handler)
ecore_main_fd_handler_active_set(exe->write_fd_handler, 0);
}
@@ -1352,6 +1283,7 @@ _ecore_exe_flush(Ecore_Exe *obj)
exe->write_data_size = 0;
exe->write_data_offset = 0;
IF_FREE(exe->write_data_buf);
+ // XXX: eoify fd handlers
if (exe->write_fd_handler)
ecore_main_fd_handler_active_set(exe->write_fd_handler, 0);
}
@@ -1361,20 +1293,14 @@ _ecore_exe_flush(Ecore_Exe *obj)
static void
_ecore_exe_dead_attach(Ecore_Exe *obj)
{
- struct _ecore_exe_dead_exe *dead;
Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
if (!exe) return;
- if (exe->doomsday_clock_dead) return;
- dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
- if (dead)
- {
- dead->pid = exe->pid;
- if (exe->cmd) dead->cmd = strdup(exe->cmd);
- IF_FN_DEL(ecore_timer_del, exe->doomsday_clock);
- exe->doomsday_clock =
- ecore_timer_add(10.0, _ecore_exe_make_sure_its_dead, dead);
- exe->doomsday_clock_dead = dead;
- }
+ if (exe->doomsday_clock) return;
+ exe->doomsday_clock = efl_add(EFL_LOOP_TIMER_CLASS, obj,
+ efl_event_callback_add(efl_added,
+ EFL_LOOP_TIMER_EVENT_TICK,
+ _ecore_exe_make_sure_its_dead,
+ obj),
+ efl_loop_timer_interval_set(efl_added, 10.0));
}
-
diff --git a/src/lib/ecore/ecore_exe_private.h b/src/lib/ecore/ecore_exe_private.h
index 17a726d368..aad66fc1da 100644
--- a/src/lib/ecore/ecore_exe_private.h
+++ b/src/lib/ecore/ecore_exe_private.h
@@ -68,10 +68,9 @@ typedef enum
struct _Ecore_Exe_Data
{
- pid_t pid;
void *data;
char *tag, *cmd;
- Ecore_Exe_Flags flags;
+ Eo *loop;
#ifdef _WIN32
HANDLE process;
@@ -124,10 +123,11 @@ struct _Ecore_Exe_Data
int start_bytes, end_bytes, start_lines, end_lines; /* Number of bytes/lines to auto pipe at start/end of stdout/stderr. */
Ecore_Timer *doomsday_clock; /* The Timer of Death. Muahahahaha. */
- void *doomsday_clock_dead; /* data for the doomsday clock */
#endif
Ecore_Exe_Cb pre_free_cb;
+ pid_t pid;
+ Ecore_Exe_Flags flags;
Eina_Bool close_stdin : 1;
};
@@ -137,7 +137,6 @@ EAPI extern int ECORE_EXE_EVENT_ADD;
EAPI extern int ECORE_EXE_EVENT_DEL;
EAPI extern int ECORE_EXE_EVENT_DATA;
EAPI extern int ECORE_EXE_EVENT_ERROR;
-extern Eina_List *_ecore_exe_exes;
Ecore_Exe *_ecore_exe_find(pid_t pid);
void *_ecore_exe_event_del_new(void);
diff --git a/src/lib/ecore/ecore_exe_win32.c b/src/lib/ecore/ecore_exe_win32.c
index 204f13e353..7ca179a482 100644
--- a/src/lib/ecore/ecore_exe_win32.c
+++ b/src/lib/ecore/ecore_exe_win32.c
@@ -528,7 +528,9 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe)
goto error;
}
- _ecore_exe_exes = eina_list_append(_ecore_exe_exes, obj);
+ exe->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
+ Efl_Loop_Data *loop = efl_data_scope_get(exe->loop, EFL_LOOP_CLASS);
+ if (loop) loop->exes = eina_list_append(loop->exes, obj);
e = calloc(1, sizeof(Ecore_Exe_Event_Add));
if (!e) goto error;
@@ -711,7 +713,8 @@ _impl_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe)
IF_FREE(exe->cmd);
- _ecore_exe_exes = eina_list_remove(_ecore_exe_exes, obj);
+ Efl_Loop_Data *loop = efl_data_scope_get(exe->loop, EFL_LOOP_CLASS);
+ if (loop) loop->exes = eina_list_remove(loop->exes, obj);
IF_FREE(exe->tag);
}
diff --git a/src/lib/ecore/ecore_job.c b/src/lib/ecore/ecore_job.c
index f302b44a99..41ddbb2148 100644
--- a/src/lib/ecore/ecore_job.c
+++ b/src/lib/ecore/ecore_job.c
@@ -35,7 +35,7 @@ _ecore_job_init(void)
void
_ecore_job_shutdown(void)
{
- _ecore_event_handler_del(_ecore_job_handler);
+ ecore_event_handler_del(_ecore_job_handler);
_ecore_job_handler = NULL;
}
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index 6a5ea42def..59631892e7 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -25,7 +25,7 @@
#endif
#ifdef HAVE_IEEEFP_H
-# include <ieeefp.h> /* for Solaris */
+# include <ieeefp.h> // for Solaris
#endif
#ifdef _MSC_VER
@@ -60,120 +60,31 @@
#include "Ecore.h"
#include "ecore_private.h"
-#if defined(HAVE_SYS_EPOLL_H) && !defined(HAVE_LIBUV)
-# define HAVE_EPOLL 1
-# include <sys/epoll.h>
-#else
-
-# define HAVE_EPOLL 0
-# define EPOLLIN 1
-# define EPOLLPRI 2
-# define EPOLLOUT 4
-# define EPOLLERR 8
-
-#define EPOLL_CTL_ADD 1
-#define EPOLL_CTL_DEL 2
-#define EPOLL_CTL_MOD 3
-
-typedef union epoll_data {
- void *ptr;
- int fd;
- uint32_t u32;
- uint64_t u64;
-} epoll_data_t;
-
-struct epoll_event
-{
- uint32_t events;
- epoll_data_t data;
-};
-
-static inline int
-epoll_create(int size EINA_UNUSED)
-{
- return -1;
-}
-
-static inline int
-epoll_wait(int epfd EINA_UNUSED,
- struct epoll_event *events EINA_UNUSED,
- int maxevents EINA_UNUSED,
- int timeout EINA_UNUSED)
-{
- return -1;
-}
-
-static inline int
-epoll_ctl(int epfd EINA_UNUSED,
- int op EINA_UNUSED,
- int fd EINA_UNUSED,
- struct epoll_event *event EINA_UNUSED)
-{
- return -1;
-}
-
-#endif
-
-#ifdef HAVE_SYS_TIMERFD_H
-# include <sys/timerfd.h>
-#else
-/* fallback code if we don't have real timerfd - reduces number of ifdefs */
-# ifndef CLOCK_MONOTONIC
-# define CLOCK_MONOTONIC 0 /* bogus value */
-# endif
-# ifndef TFD_NONBLOCK
-# define TFD_NONBLOCK 0 /* bogus value */
-# endif
-#endif /* HAVE_SYS_TIMERFD_H */
-
-#ifndef TFD_TIMER_ABSTIME
-# define TFD_TIMER_ABSTIME (1 << 0)
-#endif
-#ifndef TFD_TIMER_CANCELON_SET
-# define TFD_TIMER_CANCELON_SET (1 << 1)
-#endif
-
-#ifndef HAVE_TIMERFD_CREATE
-static inline int
-timerfd_create(int clockid EINA_UNUSED,
- int flags EINA_UNUSED)
-{
- return -1;
-}
-
-static inline int
-timerfd_settime(int fd EINA_UNUSED,
- int flags EINA_UNUSED,
- const struct itimerspec *new_value EINA_UNUSED,
- struct itimerspec *old_value EINA_UNUSED)
-{
- return -1;
-}
-
-#endif /* HAVE_TIMERFD_CREATE */
+#include "ecore_main_common.h"
#ifdef USE_G_MAIN_LOOP
# include <glib.h>
#endif
#ifdef HAVE_LIBUV
-#ifdef HAVE_NODE_UV_H
-#include <node/uv.h>
-#elif defined(HAVE_NODEJS_DEPS_UV_UV_H)
-#include <nodejs/deps/uv/uv.h>
-#elif defined(HAVE_NODEJS_DEPS_UV_INCLUDE_UV_H)
-#include <nodejs/deps/uv/include/uv.h>
-#elif defined(HAVE_NODEJS_SRC_UV_H)
-#include <nodejs/src/uv.h>
-#elif defined(HAVE_UV_H)
-#include <uv.h>
-#else
-#error No uv.h header found?
-#endif
+# ifdef HAVE_NODE_UV_H
+# include <node/uv.h>
+# elif defined(HAVE_NODEJS_DEPS_UV_UV_H)
+# include <nodejs/deps/uv/uv.h>
+# elif defined(HAVE_NODEJS_DEPS_UV_INCLUDE_UV_H)
+# include <nodejs/deps/uv/include/uv.h>
+# elif defined(HAVE_NODEJS_SRC_UV_H)
+# include <nodejs/src/uv.h>
+# elif defined(HAVE_UV_H)
+# include <uv.h>
+# else
+# error No uv.h header found?
+# endif
-#if defined HAVE_DLOPEN && ! defined _WIN32
-# include <dlfcn.h>
-#endif
+// XXX: FIXME: use eina_module
+# if defined(HAVE_DLOPEN) && !defined(_WIN32)
+# include <dlfcn.h>
+# endif
static uv_prepare_t _ecore_main_uv_prepare;
static uv_check_t _ecore_main_uv_check;
@@ -203,73 +114,70 @@ static int (*_dl_uv_check_stop)(uv_check_t* prepare);
static int (*_dl_uv_close)(uv_handle_t* handle, uv_close_cb close_cb);
#endif
-#define NS_PER_SEC (1000.0 * 1000.0 * 1000.0)
+#define NS_PER_SEC (1000000000.0)
struct _Ecore_Fd_Handler
{
EINA_INLIST;
- ECORE_MAGIC;
- Ecore_Fd_Handler *next_ready;
- int fd;
- Ecore_Fd_Handler_Flags flags;
- Ecore_Fd_Cb func;
- void *data;
- Ecore_Fd_Cb buf_func;
- void *buf_data;
- Ecore_Fd_Prep_Cb prep_func;
- void *prep_data;
- int references;
- Eina_Bool read_active : 1;
- Eina_Bool write_active : 1;
- Eina_Bool error_active : 1;
- Eina_Bool delete_me : 1;
- Eina_Bool file : 1;
+ ECORE_MAGIC;
+ Ecore_Fd_Handler *next_ready;
+ int fd;
+ Ecore_Fd_Handler_Flags flags;
+ Eo *handler;
+ Eo *loop;
+ Efl_Loop_Data *loop_data;
+ Ecore_Fd_Cb func;
+ void *data;
+ Ecore_Fd_Cb buf_func;
+ void *buf_data;
+ Ecore_Fd_Prep_Cb prep_func;
+ void *prep_data;
+ int references;
#if defined(USE_G_MAIN_LOOP)
- GPollFD gfd;
+ GPollFD gfd;
#endif
#ifdef HAVE_LIBUV
- uv_poll_t uv_handle;
+ uv_poll_t uv_handle;
#endif
+ Eina_Bool read_active : 1;
+ Eina_Bool write_active : 1;
+ Eina_Bool error_active : 1;
+ Eina_Bool delete_me : 1;
+ Eina_Bool file : 1;
};
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Fd_Handler);
-typedef struct _Efl_Loop_Promise_Simple_Data {
- union {
- Ecore_Timer *timer;
- Ecore_Idler *idler;
- };
- Eina_Promise *promise;
-} Efl_Loop_Promise_Simple_Data;
-GENERIC_ALLOC_SIZE_DECLARE(Efl_Loop_Promise_Simple_Data);
-
#ifdef _WIN32
struct _Ecore_Win32_Handler
{
EINA_INLIST;
- ECORE_MAGIC;
- HANDLE h;
- Ecore_Win32_Handle_Cb func;
- void *data;
- int references;
- Eina_Bool delete_me : 1;
+ ECORE_MAGIC;
+ HANDLE h;
+ Eo *handler;
+ Eo *loop;
+ Efl_Loop_Data *loop_data;
+ Ecore_Win32_Handle_Cb func;
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
};
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Win32_Handler);
#endif
#if !defined(USE_G_MAIN_LOOP) && !defined(HAVE_LIBUV)
-static int _ecore_main_select(double timeout);
+static int _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout);
#endif
-static void _ecore_main_prepare_handlers(void);
-static void _ecore_main_fd_handlers_cleanup(void);
+static void _ecore_main_prepare_handlers(Eo *obj, Efl_Loop_Data *pd);
+static void _ecore_main_fd_handlers_cleanup(Eo *obj, Efl_Loop_Data *pd);
#ifndef _WIN32
# ifndef USE_G_MAIN_LOOP
-static void _ecore_main_fd_handlers_bads_rem(void);
+static void _ecore_main_fd_handlers_bads_rem(Eo *obj, Efl_Loop_Data *pd);
# endif
#endif
-static void _ecore_main_fd_handlers_call(void);
-static int _ecore_main_fd_handlers_buf_call(void);
+static void _ecore_main_fd_handlers_call(Eo *obj, Efl_Loop_Data *pd);
+static int _ecore_main_fd_handlers_buf_call(Eo *obj, Efl_Loop_Data *pd);
#ifndef USE_G_MAIN_LOOP
-static void _ecore_main_loop_iterate_internal(int once_only);
+static void _ecore_main_loop_iterate_internal(Eo *obj, Efl_Loop_Data *pd, int once_only);
#endif
#ifdef _WIN32
@@ -278,127 +186,96 @@ static int _ecore_main_win32_select(int nfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);
-static void _ecore_main_win32_handlers_cleanup(void);
-#endif
-
-int in_main_loop = 0;
-
-static Eina_List *_pending_futures = NULL;
-static Eina_List *_pending_promises = NULL;
-#if (defined __GNUC__) && (__GNUC__ <= 4)
-// GCC 4 does not support compound literal for statics initializers in C99
-static Eina_Value _ecore_exit_code = {0};
-# else
-static Eina_Value _ecore_exit_code = EINA_VALUE_EMPTY;
-#endif
-static int do_quit = 0;
-static Ecore_Fd_Handler *fd_handlers = NULL;
-static Ecore_Fd_Handler *fd_handler_current = NULL;
-static Eina_List *fd_handlers_with_prep = NULL;
-static Eina_List *file_fd_handlers = NULL;
-static Eina_List *fd_handlers_with_buffer = NULL;
-static Eina_List *fd_handlers_to_delete = NULL;
-
-/* single linked list of ready fdhs, terminated by loop to self */
-static Ecore_Fd_Handler *fd_handlers_to_call;
-static Ecore_Fd_Handler *fd_handlers_to_call_current;
-
-#ifdef _WIN32
-static Ecore_Win32_Handler *win32_handlers = NULL;
-static Ecore_Win32_Handler *win32_handler_current = NULL;
-static Eina_List *win32_handlers_to_delete = NULL;
+static void _ecore_main_win32_handlers_cleanup(Eo *obj, Efl_Loop_Data *pd);
#endif
-#ifdef _WIN32
-Ecore_Select_Function main_loop_select = _ecore_main_win32_select;
-#else
-# if !defined EXOTIC_NO_SELECT
-# include <sys/select.h>
-Ecore_Select_Function main_loop_select = select;
-# else
-Ecore_Select_Function main_loop_select = NULL;
-# endif
-#endif
+static void _ecore_main_loop_setup(Eo *obj, Efl_Loop_Data *pd);
+static void _ecore_main_loop_clear(Eo *obj, Efl_Loop_Data *pd);
+// for legacy mainloop only and not other loops
+int in_main_loop = 0;
#ifndef USE_G_MAIN_LOOP
static double t1 = 0.0;
static double t2 = 0.0;
#endif
-#ifdef HAVE_EPOLL
-static int epoll_fd = -1;
-static pid_t epoll_pid;
+#ifdef _WIN32
+Ecore_Select_Function main_loop_select = _ecore_main_win32_select;
+static Ecore_Select_Function general_loop_select = _ecore_main_win32_select;
+#else
+# include <sys/select.h>
+Ecore_Select_Function main_loop_select = select;
+static Ecore_Select_Function general_loop_select = select;
#endif
-static int timer_fd = -1;
#ifdef USE_G_MAIN_LOOP
-static GPollFD ecore_epoll_fd;
-static GPollFD ecore_timer_fd;
-static GSource *ecore_glib_source;
-static guint ecore_glib_source_id;
+static GPollFD ecore_epoll_fd;
+static GPollFD ecore_timer_fd;
+static GSource *ecore_glib_source;
+static guint ecore_glib_source_id;
static GMainLoop *ecore_main_loop;
-static gboolean ecore_idling;
-static gboolean _ecore_glib_idle_enterer_called;
-static gboolean ecore_fds_ready;
+static gboolean ecore_idling;
+static gboolean _ecore_glib_idle_enterer_called;
+static gboolean ecore_fds_ready;
#endif
#ifdef EFL_EXTRA_SANITY_CHECKS
static inline void
-_ecore_fd_valid(void)
+_ecore_fd_valid(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
{
-#ifdef HAVE_EPOLL
- if (epoll_fd >= 0)
+# ifdef HAVE_EPOLL
+ if ((pd->epoll_fd >= 0) &&
+ (fcntl(pd->epoll_fd, F_GETFD) < 0))
{
- if (fcntl(epoll_fd, F_GETFD) < 0)
- {
- ERR("arghhh you caught me! report a backtrace to edevel!");
-#ifdef HAVE_PAUSE
- pause();
-#else
- sleep(60);
-#endif
- }
+ ERR("arghhh you caught me! report a backtrace to edevel!");
+# ifdef HAVE_PAUSE
+ pause();
+# else
+ sleep(60);
+# endif
}
-#endif
+# endif
}
#endif
static inline void
-_ecore_try_add_to_call_list(Ecore_Fd_Handler *fdh)
+_ecore_try_add_to_call_list(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, Ecore_Fd_Handler *fdh)
{
- /* check if this fdh is already in the list */
+ // check if this fdh is already in the list
if (fdh->next_ready)
{
- DBG("next_ready");
- return;
+ DBG("next_ready");
+ return;
}
if (fdh->read_active || fdh->write_active || fdh->error_active)
{
- DBG("added");
- /*
- * make sure next_ready is non-null by pointing to ourselves
- * use that to indicate this fdh is in the ready list
- * insert at the head of the list to avoid trouble
- */
- fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh;
- fd_handlers_to_call = fdh;
+ DBG("added");
+ // make sure next_ready is non-null by pointing to ourselves
+ // use that to indicate this fdh is in the ready list
+ // insert at the head of the list to avoid trouble
+ fdh->next_ready = pd->fd_handlers_to_call ? pd->fd_handlers_to_call : fdh;
+ pd->fd_handlers_to_call = fdh;
}
}
+static inline void
+_throttle_do(Efl_Loop_Data *pd)
+{
+ if (pd->throttle == 0) return
+ eina_evlog("+throttle", NULL, 0.0, NULL);
+ usleep(pd->throttle);
+ eina_evlog("-throttle", NULL, 0.0, NULL);
+}
+
#ifdef HAVE_EPOLL
static inline int
-_ecore_get_epoll_fd(void)
+_ecore_get_epoll_fd(Eo *obj, Efl_Loop_Data *pd)
{
- if (epoll_pid && (epoll_pid != getpid()))
- {
- /* forked! */
- _ecore_main_loop_shutdown();
- }
- if ((epoll_pid == 0) && (epoll_fd < 0))
- {
- _ecore_main_loop_init();
- }
- return epoll_fd;
+ if (pd->epoll_pid && (pd->epoll_pid != getpid())) // forked!
+ _ecore_main_loop_clear(obj, pd);
+ if ((pd->epoll_pid == 0) && (pd->epoll_fd < 0))
+ _ecore_main_loop_setup(obj, pd);
+ return pd->epoll_fd;
}
static inline int
@@ -420,7 +297,7 @@ static inline int
_ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh)
{
int events = 0;
- if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN;
+ if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN;
if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT;
if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR | EPOLLPRI;
return events;
@@ -432,7 +309,7 @@ static inline int
_gfd_events_from_fdh(Ecore_Fd_Handler *fdh)
{
int events = 0;
- if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN;
+ if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN;
if (fdh->flags & ECORE_FD_WRITE) events |= G_IO_OUT;
if (fdh->flags & ECORE_FD_ERROR) events |= G_IO_ERR;
return events;
@@ -441,42 +318,42 @@ _gfd_events_from_fdh(Ecore_Fd_Handler *fdh)
#ifdef HAVE_LIBUV
static void
-_ecore_main_uv_poll_cb(uv_poll_t* handle, int status, int events)
+_ecore_main_uv_poll_cb(uv_poll_t *handle, int status, int events)
{
- DBG("_ecore_main_uv_poll_cb %p status %d events %d", (void*)handle->data, status, events);
- Ecore_Fd_Handler* fdh = handle->data;
+ Eo *obj = ML_OBJ;
+ Efl_Loop_Data *pd = ML_DAT;
- if(_ecore_main_uv_idling)
+ DBG("_ecore_main_uv_poll_cb %p status %d events %d",
+ (void *)handle->data, status, events);
+ Ecore_Fd_Handler *fdh = handle->data;
+
+ if (_ecore_main_uv_idling)
{
DBG("not IDLE anymore");
_ecore_main_uv_idling = EINA_FALSE;
- _ecore_idle_exiter_call(_mainloop_singleton);
+ _ecore_idle_exiter_call(obj);
_ecore_animator_run_reset();
}
-
- if (status)
- fdh->error_active = EINA_TRUE;
- if (events & UV_READABLE)
- fdh->read_active = EINA_TRUE;
- if (events & UV_WRITABLE)
- fdh->write_active = EINA_TRUE;
- _ecore_try_add_to_call_list(fdh);
+ if (status) fdh->error_active = EINA_TRUE;
+ if (events & UV_READABLE) fdh->read_active = EINA_TRUE;
+ if (events & UV_WRITABLE) fdh->write_active = EINA_TRUE;
+
+ _ecore_try_add_to_call_list(obj, pd, fdh);
- _ecore_main_fd_handlers_call();
- if (fd_handlers_with_buffer)
- _ecore_main_fd_handlers_buf_call();
- _ecore_signal_received_process();
- _ecore_event_call();
- _ecore_main_fd_handlers_cleanup();
- _efl_loop_timer_expired_timers_call(_ecore_time_loop_time);
+ _ecore_main_fd_handlers_call(obj, pd);
+ if (pd->fd_handlers_with_buffer) _ecore_main_fd_handlers_buf_call(obj, pd);
+ _ecore_signal_received_process(obj, pd);
+ efl_loop_message_process(obj);
+ _ecore_main_fd_handlers_cleanup(obj, pd);
+ _efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time);
}
static int
_ecore_main_uv_events_from_fdh(Ecore_Fd_Handler *fdh)
{
int events = 0;
- if (fdh->flags & ECORE_FD_READ) events |= UV_READABLE;
+ if (fdh->flags & ECORE_FD_READ) events |= UV_READABLE;
if (fdh->flags & ECORE_FD_WRITE) events |= UV_WRITABLE;
DBG("events is %d", (int)events);
return events;
@@ -484,50 +361,52 @@ _ecore_main_uv_events_from_fdh(Ecore_Fd_Handler *fdh)
#endif
static inline int
-_ecore_main_fdh_poll_add(Ecore_Fd_Handler *fdh)
+_ecore_main_fdh_poll_add(Efl_Loop_Data *pd EINA_UNUSED, Ecore_Fd_Handler *fdh)
{
DBG("_ecore_main_fdh_poll_add");
int r = 0;
#ifdef HAVE_EPOLL
-#ifdef HAVE_LIBUV
- if(!_dl_uv_run)
-#endif
+# ifdef HAVE_LIBUV
+ if (!_dl_uv_run)
+# endif
{
- if ((!fdh->file) && (epoll_fd >= 0))
- {
- r = _ecore_epoll_add(_ecore_get_epoll_fd(), fdh->fd,
- _ecore_poll_events_from_fdh(fdh), fdh);
- }
+ if ((!fdh->file) && (pd->epoll_fd >= 0))
+ r = _ecore_epoll_add(_ecore_get_epoll_fd(fdh->loop, pd), fdh->fd,
+ _ecore_poll_events_from_fdh(fdh), fdh);
}
-#ifdef HAVE_LIBUV
+# ifdef HAVE_LIBUV
else
-#endif
+# endif
#endif
{
#ifdef HAVE_LIBUV
- if(!fdh->file)
- {
- DBG("_ecore_main_fdh_poll_add libuv socket %p", fdh);
- fdh->uv_handle.data = fdh;
- DBG("_ecore_main_fdh_poll_add2 %p", fdh);
- _dl_uv_poll_init_socket(_dl_uv_default_loop(), &fdh->uv_handle, fdh->fd);
- DBG("_ecore_main_fdh_poll_add3 %p", fdh->uv_handle.data);
- _dl_uv_poll_start(&fdh->uv_handle, _ecore_main_uv_events_from_fdh(fdh)
- , _ecore_main_uv_poll_cb);
- DBG("_ecore_main_fdh_poll_add libuv DONE");
- }
- else
- {
- DBG("_ecore_main_fdh_poll_add libuv file");
- fdh->uv_handle.data = fdh;
- DBG("_ecore_main_fdh_poll_add2 %p", fdh);
- _dl_uv_poll_init(_dl_uv_default_loop(), &fdh->uv_handle, fdh->fd);
- DBG("_ecore_main_fdh_poll_add3 %p", fdh->uv_handle.data);
- _dl_uv_poll_start(&fdh->uv_handle, _ecore_main_uv_events_from_fdh(fdh)
- , _ecore_main_uv_poll_cb);
- DBG("_ecore_main_fdh_poll_add libuv DONE");
- }
+ if (!fdh->file)
+ {
+ DBG("_ecore_main_fdh_poll_add libuv socket %p", fdh);
+ fdh->uv_handle.data = fdh;
+ DBG("_ecore_main_fdh_poll_add2 %p", fdh);
+ _dl_uv_poll_init_socket(_dl_uv_default_loop(),
+ &fdh->uv_handle, fdh->fd);
+ DBG("_ecore_main_fdh_poll_add3 %p", fdh->uv_handle.data);
+ _dl_uv_poll_start(&fdh->uv_handle,
+ _ecore_main_uv_events_from_fdh(fdh)
+ , _ecore_main_uv_poll_cb);
+ DBG("_ecore_main_fdh_poll_add libuv DONE");
+ }
+ else
+ {
+ DBG("_ecore_main_fdh_poll_add libuv file");
+ fdh->uv_handle.data = fdh;
+ DBG("_ecore_main_fdh_poll_add2 %p", fdh);
+ _dl_uv_poll_init(_dl_uv_default_loop(),
+ &fdh->uv_handle, fdh->fd);
+ DBG("_ecore_main_fdh_poll_add3 %p", fdh->uv_handle.data);
+ _dl_uv_poll_start(&fdh->uv_handle,
+ _ecore_main_uv_events_from_fdh(fdh)
+ , _ecore_main_uv_poll_cb);
+ DBG("_ecore_main_fdh_poll_add libuv DONE");
+ }
#elif defined(USE_G_MAIN_LOOP)
fdh->gfd.fd = fdh->fd;
fdh->gfd.events = _gfd_events_from_fdh(fdh);
@@ -540,47 +419,45 @@ _ecore_main_fdh_poll_add(Ecore_Fd_Handler *fdh)
}
static inline void
-_ecore_main_fdh_poll_del(Ecore_Fd_Handler *fdh)
+_ecore_main_fdh_poll_del(Efl_Loop_Data *pd, Ecore_Fd_Handler *fdh)
{
#ifdef HAVE_EPOLL
-#ifdef HAVE_LIBUV
- if(!_dl_uv_run)
-#endif
- {
- if ((!fdh->file) && (epoll_fd >= 0))
- {
- struct epoll_event ev;
- int efd = _ecore_get_epoll_fd();
-
- memset(&ev, 0, sizeof (ev));
- DBG("removing poll on %d", fdh->fd);
- /* could get an EBADF if somebody closed the FD before removing it */
- if ((epoll_ctl(efd, EPOLL_CTL_DEL, fdh->fd, &ev) < 0))
- {
- if (errno == EBADF)
- {
- WRN("fd %d was closed, can't remove from epoll - reinit!",
- fdh->fd);
- _ecore_main_loop_shutdown();
- _ecore_main_loop_init();
- }
- else
- {
- ERR("Failed to delete epoll fd %d! (errno=%d)", fdh->fd, errno);
- }
- }
- }
+# ifdef HAVE_LIBUV
+ if (!_dl_uv_run)
+# endif
+ {
+ if ((!fdh->file) && (pd->epoll_fd >= 0))
+ {
+ struct epoll_event ev;
+ int efd = _ecore_get_epoll_fd(fdh->loop, pd);
+
+ memset(&ev, 0, sizeof (ev));
+ DBG("removing poll on %d", fdh->fd);
+ // could get an EBADF if somebody closed the FD before removing
+ if ((epoll_ctl(efd, EPOLL_CTL_DEL, fdh->fd, &ev) < 0))
+ {
+ if (errno == EBADF)
+ {
+ WRN("fd %d closed, can't remove from epoll - reinit!",
+ fdh->fd);
+ _ecore_main_loop_clear(fdh->loop, pd);
+ _ecore_main_loop_setup(fdh->loop, pd);
+ }
+ else ERR("Failed to delete epoll fd %d! (errno=%d)",
+ fdh->fd, errno);
+ }
+ }
}
-#ifdef HAVE_LIBUV
+# ifdef HAVE_LIBUV
else
-#endif
+# endif
#endif
{
#ifdef HAVE_LIBUV
- DBG("_ecore_main_fdh_poll_del libuv %p", fdh);
- uv_handle_t* h = (uv_handle_t*)&fdh->uv_handle;
- _dl_uv_close(h, 0);
- DBG("_ecore_main_fdh_poll_del libuv DONE");
+ DBG("_ecore_main_fdh_poll_del libuv %p", fdh);
+ uv_handle_t* h = (uv_handle_t*)&fdh->uv_handle;
+ _dl_uv_close(h, 0);
+ DBG("_ecore_main_fdh_poll_del libuv DONE");
#elif USE_G_MAIN_LOOP
fdh->gfd.fd = fdh->fd;
fdh->gfd.events = _gfd_events_from_fdh(fdh);
@@ -592,35 +469,35 @@ _ecore_main_fdh_poll_del(Ecore_Fd_Handler *fdh)
}
static inline int
-_ecore_main_fdh_poll_modify(Ecore_Fd_Handler *fdh)
+_ecore_main_fdh_poll_modify(Efl_Loop_Data *pd EINA_UNUSED, Ecore_Fd_Handler *fdh)
{
DBG("_ecore_main_fdh_poll_modify %p", fdh);
int r = 0;
#ifdef HAVE_EPOLL
-#ifdef HAVE_LIBUV
- if(!_dl_uv_run)
-#endif
+# ifdef HAVE_LIBUV
+ if (!_dl_uv_run)
+# endif
{
- if ((!fdh->file) && (epoll_fd >= 0))
- {
- struct epoll_event ev;
- int efd = _ecore_get_epoll_fd();
-
- memset(&ev, 0, sizeof (ev));
- ev.events = _ecore_poll_events_from_fdh(fdh);
- ev.data.ptr = fdh;
- DBG("modifing epoll on %d to %08x", fdh->fd, ev.events);
- r = epoll_ctl(efd, EPOLL_CTL_MOD, fdh->fd, &ev);
- }
+ if ((!fdh->file) && (pd->epoll_fd >= 0))
+ {
+ struct epoll_event ev;
+ int efd = _ecore_get_epoll_fd(fdh->loop, pd);
+
+ memset(&ev, 0, sizeof (ev));
+ ev.events = _ecore_poll_events_from_fdh(fdh);
+ ev.data.ptr = fdh;
+ DBG("modifing epoll on %d to %08x", fdh->fd, ev.events);
+ r = epoll_ctl(efd, EPOLL_CTL_MOD, fdh->fd, &ev);
+ }
}
-#ifdef HAVE_LIBUV
+# ifdef HAVE_LIBUV
else
-#endif
+# endif
#endif
{
#ifdef HAVE_LIBUV
- _dl_uv_poll_start(&fdh->uv_handle, _ecore_main_uv_events_from_fdh(fdh)
- , _ecore_main_uv_poll_cb);
+ _dl_uv_poll_start(&fdh->uv_handle, _ecore_main_uv_events_from_fdh(fdh)
+ , _ecore_main_uv_poll_cb);
#elif defined(USE_G_MAIN_LOOP)
fdh->gfd.fd = fdh->fd;
fdh->gfd.events = _gfd_events_from_fdh(fdh);
@@ -633,12 +510,12 @@ _ecore_main_fdh_poll_modify(Ecore_Fd_Handler *fdh)
#ifdef HAVE_EPOLL
static inline int
-_ecore_main_fdh_epoll_mark_active(void)
+_ecore_main_fdh_epoll_mark_active(Eo *obj, Efl_Loop_Data *pd)
{
DBG("_ecore_main_fdh_epoll_mark_active");
struct epoll_event ev[32];
int i, ret;
- int efd = _ecore_get_epoll_fd();
+ int efd = _ecore_get_epoll_fd(obj, pd);
memset(&ev, 0, sizeof (ev));
ret = epoll_wait(efd, ev, sizeof(ev) / sizeof(struct epoll_event), 0);
@@ -666,42 +543,33 @@ _ecore_main_fdh_epoll_mark_active(void)
continue;
}
- if (ev[i].events & EPOLLIN)
- fdh->read_active = EINA_TRUE;
- if (ev[i].events & EPOLLOUT)
- fdh->write_active = EINA_TRUE;
- if (ev[i].events & EPOLLERR)
- fdh->error_active = EINA_TRUE;
+ if (ev[i].events & EPOLLIN) fdh->read_active = EINA_TRUE;
+ if (ev[i].events & EPOLLOUT) fdh->write_active = EINA_TRUE;
+ if (ev[i].events & EPOLLERR) fdh->error_active = EINA_TRUE;
- _ecore_try_add_to_call_list(fdh);
+ _ecore_try_add_to_call_list(obj, pd, fdh);
}
-
return ret;
}
#endif
#ifdef USE_G_MAIN_LOOP
-
static inline int
-_ecore_main_fdh_glib_mark_active(void)
+_ecore_main_fdh_glib_mark_active(Eo *obj, Efl_Loop_Data *pd)
{
Ecore_Fd_Handler *fdh;
int ret = 0;
/* call the prepare callback for all handlers */
- EINA_INLIST_FOREACH(fd_handlers, fdh)
+ EINA_INLIST_FOREACH(pd->fd_handlers, fdh)
{
- if (fdh->delete_me)
- continue;
+ if (fdh->delete_me) continue;
- if (fdh->gfd.revents & G_IO_IN)
- fdh->read_active = EINA_TRUE;
- if (fdh->gfd.revents & G_IO_OUT)
- fdh->write_active = EINA_TRUE;
- if (fdh->gfd.revents & G_IO_ERR)
- fdh->error_active = EINA_TRUE;
+ if (fdh->gfd.revents & G_IO_IN) fdh->read_active = EINA_TRUE;
+ if (fdh->gfd.revents & G_IO_OUT) fdh->write_active = EINA_TRUE;
+ if (fdh->gfd.revents & G_IO_ERR) fdh->error_active = EINA_TRUE;
- _ecore_try_add_to_call_list(fdh);
+ _ecore_try_add_to_call_list(obj, fdh);
if (fdh->gfd.revents & (G_IO_IN | G_IO_OUT | G_IO_ERR)) ret++;
}
@@ -714,159 +582,164 @@ static gboolean
_ecore_main_gsource_prepare(GSource *source EINA_UNUSED,
gint *next_time)
{
+ Eo *obj = ML_OBJ;
+ Efl_Loop_Data *pd = ML_DAT;
gboolean ready = FALSE;
in_main_loop++;
+ pd->in_loop = in_main_loop;
- if (!ecore_idling && !_ecore_glib_idle_enterer_called)
+ if ((!ecore_idling) && (!_ecore_glib_idle_enterer_called))
{
- _ecore_time_loop_time = ecore_time_get();
- _efl_loop_timer_expired_timers_call(_ecore_time_loop_time);
+ pd->loop_time = _ecore_time_loop_time = ecore_time_get();
+ _efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time);
- _ecore_idle_enterer_call(_mainloop_singleton);
+ _ecore_idle_enterer_call(obj);
_ecore_throttle();
+ _throttle_do(pd);
_ecore_glib_idle_enterer_called = FALSE;
- if (fd_handlers_with_buffer)
- _ecore_main_fd_handlers_buf_call();
+ if (pd->fd_handlers_with_buffer)
+ _ecore_main_fd_handlers_buf_call(obj, pd);
}
- _ecore_signal_received_process();
+ _ecore_signal_received_process(obj, pd);
- /* don't check fds if somebody quit */
+ // don't check fds if somebody quit
if (g_main_loop_is_running(ecore_main_loop))
{
- /* only set idling state in dispatch */
- if (ecore_idling && !_ecore_idler_exist(_mainloop_singleton) && !_ecore_event_exist())
- {
- if (_efl_loop_timers_exists())
- {
- int r = -1;
- double t = _efl_loop_timer_next_get();
-
- if ((timer_fd >= 0) && (t > 0.0))
- {
- struct itimerspec ts;
-
- ts.it_interval.tv_sec = 0;
- ts.it_interval.tv_nsec = 0;
- ts.it_value.tv_sec = t;
- ts.it_value.tv_nsec = fmod(t * NS_PER_SEC, NS_PER_SEC);
-
- /* timerfd cannot sleep for 0 time */
- if (ts.it_value.tv_sec || ts.it_value.tv_nsec)
- {
- r = timerfd_settime(timer_fd, 0, &ts, NULL);
- if (r < 0)
- {
- ERR("timer set returned %d (errno=%d)", r, errno);
- close(timer_fd);
- timer_fd = -1;
- }
- else
- INF("sleeping for %ld s %06ldus",
- ts.it_value.tv_sec,
- ts.it_value.tv_nsec / 1000);
- }
- }
- if (r == -1)
- {
- *next_time = ceil(t * 1000.0);
- if (t == 0.0)
- ready = TRUE;
- }
- }
- else
- *next_time = -1;
- }
- else
- {
- *next_time = 0;
- if (_ecore_event_exist())
- ready = TRUE;
- }
-
- if (fd_handlers_with_prep)
- _ecore_main_prepare_handlers();
+ // only set idling state in dispatch
+ if (ecore_idling && (!_ecore_idler_exist(obj)) &&
+ (!efl_loop_message_exists(obj)))
+ {
+ if (_efl_loop_timers_exists(obj, pd))
+ {
+ int r = -1;
+ double t = _efl_loop_timer_next_get(obj, pd);
+
+ if ((timer_fd >= 0) && (t > 0.0))
+ {
+ struct itimerspec ts;
+
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+ ts.it_value.tv_sec = t;
+ ts.it_value.tv_nsec = fmod(t * NS_PER_SEC, NS_PER_SEC);
+
+ // timerfd cannot sleep for 0 time
+ if (ts.it_value.tv_sec || ts.it_value.tv_nsec)
+ {
+ r = timerfd_settime(timer_fd, 0, &ts, NULL);
+ if (r < 0)
+ {
+ ERR("timer set returned %d (errno=%d)",
+ r, errno);
+ close(timer_fd);
+ timer_fd = -1;
+ }
+ else INF("sleeping for %ld s %06ldus",
+ ts.it_value.tv_sec,
+ ts.it_value.tv_nsec / 1000);
+ }
+ }
+ if (r == -1)
+ {
+ *next_time = ceil(t * 1000.0);
+ if (t == 0.0) ready = TRUE;
+ }
+ }
+ else *next_time = -1;
+ }
+ else
+ {
+ *next_time = 0;
+ if (efl_loop_message_exists(obj)) ready = TRUE;
+ }
+
+ if (pd->fd_handlers_with_prep) _ecore_main_prepare_handlers(obj, pd);
}
- else
- ready = TRUE;
+ else ready = TRUE;
in_main_loop--;
+ pd->in_loop = in_main_loop;
DBG("leave, timeout = %d", *next_time);
- /* ready if we're not running (about to quit) */
+ // ready if we're not running (about to quit)
return ready;
}
static gboolean
_ecore_main_gsource_check(GSource *source EINA_UNUSED)
{
+ Eo *obj = ML_OBJ;
+ Efl_Loop_Data *pd = ML_DAT;
gboolean ret = FALSE;
in_main_loop++;
-
- /* check if old timers expired */
- if (ecore_idling && !_ecore_idler_exist(_mainloop_singleton) && !_ecore_event_exist())
+ pd->in_loop = in_main_loop;
+ // check if old timers expired
+ if (ecore_idling && (!_ecore_idler_exist(obj)) &&
+ (!efl_loop_message_exists(obj)))
{
if (timer_fd >= 0)
{
uint64_t count = 0;
int r = read(timer_fd, &count, sizeof count);
if ((r == -1) && (errno == EAGAIN))
- ;
- else if (r == sizeof count)
- ret = TRUE;
+ {
+ }
+ else if (r == sizeof count) ret = TRUE;
else
{
- /* unexpected things happened... fail back to old way */
- ERR("timer read returned %d (errno=%d)", r, errno);
- close(timer_fd);
- timer_fd = -1;
+ // unexpected things happened... fail back to old way
+ ERR("timer read returned %d (errno=%d)", r, errno);
+ close(timer_fd);
+ timer_fd = -1;
}
}
}
- else
- ret = TRUE;
+ else ret = TRUE;
- /* check if fds are ready */
+ // check if fds are ready
#ifdef HAVE_EPOLL
- if (epoll_fd >= 0)
- ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active() > 0);
+ if (pd->epoll_fd >= 0)
+ ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active(obj, pd) > 0);
else
#endif
- ecore_fds_ready = (_ecore_main_fdh_glib_mark_active() > 0);
- _ecore_main_fd_handlers_cleanup();
- if (ecore_fds_ready)
- ret = TRUE;
+ ecore_fds_ready = (_ecore_main_fdh_glib_mark_active(obj, pd) > 0);
+ _ecore_main_fd_handlers_cleanup(obj, pd);
+ if (ecore_fds_ready) ret = TRUE;
- /* check timers after updating loop time */
- if (!ret && _efl_loop_timers_exists())
- ret = (0.0 == _efl_loop_timer_next_get());
+ // check timers after updating loop time
+ if (!ret && _efl_loop_timers_exists(obj, pd))
+ ret = (0.0 == _efl_loop_timer_next_get(obj, pd));
in_main_loop--;
-
+ pd->in_loop = in_main_loop;
return ret;
}
-/* like we just came out of main_loop_select in _ecore_main_select */
+// like we just came out of main_loop_select in _ecore_main_select
static gboolean
_ecore_main_gsource_dispatch(GSource *source EINA_UNUSED,
GSourceFunc callback EINA_UNUSED,
gpointer user_data EINA_UNUSED)
{
+ Eo *obj = ML_OBJ;
+ Efl_Loop_Data *pd = ML_DAT;
gboolean events_ready, timers_ready, idlers_ready;
double next_time;
- _ecore_time_loop_time = ecore_time_get();
- _efl_loop_timer_enable_new();
- next_time = _efl_loop_timer_next_get();
+ pd->loop_time = ecore_time_get();
+ _efl_loop_timer_enable_new(obj, pd);
+ next_time = _efl_loop_timer_next_get(obj, pd);
- events_ready = _ecore_event_exist();
- timers_ready = _efl_loop_timers_exists() && (0.0 == next_time);
- idlers_ready = _ecore_idler_exist(_mainloop_singleton);
+ events_ready = efl_loop_message_exists(obj);
+ timers_ready = _efl_loop_timers_exists(obj, pd) && (0.0 == next_time);
+ idlers_ready = _ecore_idler_exist(obj);
in_main_loop++;
+ pd->in_loop = in_main_loop;
DBG("enter idling=%d fds=%d events=%d timers=%d (next=%.2f) idlers=%d",
ecore_idling, ecore_fds_ready, events_ready,
timers_ready, next_time, idlers_ready);
@@ -874,51 +747,50 @@ _ecore_main_gsource_dispatch(GSource *source EINA_UNUSED,
if (ecore_idling && events_ready)
{
_ecore_animator_run_reset();
- _ecore_idle_exiter_call(_mainloop_singleton);
+ _ecore_idle_exiter_call(obj);
ecore_idling = 0;
}
- else if (!ecore_idling && !events_ready)
- {
- ecore_idling = 1;
- }
+ else if (!ecore_idling && !events_ready) ecore_idling = 1;
if (ecore_idling)
{
- _ecore_idler_all_call(_mainloop_singleton);
+ _ecore_idler_all_call(obj);
- events_ready = _ecore_event_exist();
+ events_ready = efl_loop_message_exists(obj);
if (ecore_fds_ready || events_ready || timers_ready)
{
_ecore_animator_run_reset();
- _ecore_idle_exiter_call(_mainloop_singleton);
+ _ecore_idle_exiter_call(obj);
ecore_idling = 0;
}
}
- /* process events */
+ // process events
if (!ecore_idling)
{
- _ecore_main_fd_handlers_call();
- if (fd_handlers_with_buffer)
- _ecore_main_fd_handlers_buf_call();
- _ecore_signal_received_process();
- _ecore_event_call();
- _ecore_main_fd_handlers_cleanup();
+ _ecore_main_fd_handlers_call(obj, pd);
+ if (pd->fd_handlers_with_buffer)
+ _ecore_main_fd_handlers_buf_call(obj, pd);
+ _ecore_signal_received_process(obj, pd);
+ efl_loop_message_process(obj);
+ _ecore_main_fd_handlers_cleanup(obj, pd);
- _efl_loop_timer_expired_timers_call(_ecore_time_loop_time);
+ _efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time);
- _ecore_idle_enterer_call(_mainloop_singleton);
+ _ecore_idle_enterer_call(obj);
_ecore_throttle();
+ _throttle_do(pd);
_ecore_glib_idle_enterer_called = TRUE;
- if (fd_handlers_with_buffer)
- _ecore_main_fd_handlers_buf_call();
+ if (pd->fd_handlers_with_buffer)
+ _ecore_main_fd_handlers_buf_call(obj, pd);
}
in_main_loop--;
+ pd->in_loop = in_main_loop;
- return TRUE; /* what should be returned here? */
+ return TRUE; // what should be returned here?
}
static void
@@ -928,432 +800,438 @@ _ecore_main_gsource_finalize(GSource *source EINA_UNUSED)
static GSourceFuncs ecore_gsource_funcs =
{
- .prepare = _ecore_main_gsource_prepare,
- .check = _ecore_main_gsource_check,
+ .prepare = _ecore_main_gsource_prepare,
+ .check = _ecore_main_gsource_check,
.dispatch = _ecore_main_gsource_dispatch,
.finalize = _ecore_main_gsource_finalize,
};
-
#endif
-#ifdef HAVE_SYS_TIMERFD_H
-static int realtime_fd = -1;
-
-static void detect_time_changes_start(void);
-static Eina_Bool
-_realtime_update(void *data EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED)
-{
- char buf[64];
-
- if (read(realtime_fd, buf, sizeof(buf)) >= 0) return EINA_TRUE;
-
- DBG("system clock changed");
- ecore_event_add(ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED, NULL, NULL, NULL);
-
- close(realtime_fd);
- realtime_fd = -1;
- detect_time_changes_start();
- return EINA_FALSE;
-}
-#endif
+#ifdef HAVE_LIBUV
+static inline void _ecore_main_loop_uv_check(uv_check_t *handle);
+static void _ecore_main_loop_uv_prepare(uv_prepare_t *handle);
static void
-detect_time_changes_start(void)
+_ecore_main_loop_timer_run(uv_timer_t *timer EINA_UNUSED)
{
-#ifdef HAVE_SYS_TIMERFD_H
- struct itimerspec its;
-
- if (realtime_fd >= 0) return;
+ Eo *obj = ML_OBJ;
+ Efl_Loop_Data *pd = ML_DAT;
- realtime_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC);
- if (realtime_fd < 0) return;
-
- memset(&its, 0, sizeof(its));
- its.it_value.tv_sec = 0x7ffffff0; // end of time - 0xf
- if (timerfd_settime(realtime_fd,
- TFD_TIMER_ABSTIME | TFD_TIMER_CANCELON_SET,
- &its, NULL) < 0)
+ if (_ecore_main_uv_idling)
{
- WRN("Couldn't arm timerfd to detect clock changes: %s",
- strerror(errno));
- close(realtime_fd);
- realtime_fd = -1;
- return;
+ _ecore_main_uv_idling = EINA_FALSE;
+ _ecore_idle_exiter_call(obj);
+ _ecore_animator_run_reset();
}
-
- ecore_main_fd_handler_add(realtime_fd, ECORE_FD_READ,
- _realtime_update, NULL, NULL, NULL);
-#endif
+ pd->loop_time = ecore_time_get();
+ _ecore_main_loop_uv_check(NULL);
+ _ecore_main_loop_uv_prepare(NULL);
}
-static void
-detect_time_changes_stop(void)
+static inline void
+_ecore_main_loop_uv_check(uv_check_t *handle EINA_UNUSED)
{
-#ifdef HAVE_SYS_TIMERFD_H
- if (realtime_fd > 0)
- {
- close(realtime_fd);
- realtime_fd = -1;
- }
-#endif
-}
+ Eo *obj = ML_OBJ;
+ Efl_Loop_Data *pd = ML_DAT;
-
-#ifdef HAVE_LIBUV
-static inline
-void
-_ecore_main_loop_uv_check(uv_check_t* handle EINA_UNUSED);
-static void _ecore_main_loop_uv_prepare(uv_prepare_t* handle);
-
-static
-void _ecore_main_loop_timer_run(uv_timer_t* timer EINA_UNUSED)
-{
- if(_ecore_main_uv_idling)
- {
- _ecore_main_uv_idling = EINA_FALSE;
- _ecore_idle_exiter_call(_mainloop_singleton);
- _ecore_animator_run_reset();
- }
- _ecore_time_loop_time = ecore_time_get();
- _ecore_main_loop_uv_check(NULL);
-
- _ecore_main_loop_uv_prepare(NULL);
-}
-static void _ecore_main_loop_uv_prepare(uv_prepare_t* handle);
-
-static inline
-void
-_ecore_main_loop_uv_check(uv_check_t* handle EINA_UNUSED)
-{
DBG("_ecore_main_loop_uv_check idling? %d", (int)_ecore_main_uv_idling);
in_main_loop++;
+ pd->in_loop = in_main_loop;
- if(do_quit)
- goto quit;
+ if (pd->do_quit) goto quit;
do
{
- _ecore_main_fd_handlers_call();
- if (fd_handlers_with_buffer)
- _ecore_main_fd_handlers_buf_call();
- _ecore_signal_received_process();
- _ecore_event_call();
- _ecore_main_fd_handlers_cleanup();
- _efl_loop_timer_expired_timers_call(_ecore_time_loop_time);
+ _ecore_main_fd_handlers_call(obj, pd);
+ if (pd->fd_handlers_with_buffer)
+ _ecore_main_fd_handlers_buf_call(obj, pd);
+ _ecore_signal_received_process(obj, pd);
+ efl_loop_message_process(obj);
+ _ecore_main_fd_handlers_cleanup(obj, pd);
+ _efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time);
}
- while(fd_handlers_to_call);
+ while (pd->fd_handlers_to_call);
quit:
in_main_loop--;
+ pd->in_loop = in_main_loop;
}
#endif
-void
-_ecore_main_loop_init(void)
+static void
+_ecore_main_loop_setup(Eo *obj, Efl_Loop_Data *pd)
{
- // Please note that this function is being also called in case of a bad fd to reset the main loop.
-
- DBG("_ecore_main_loop_init");
+ // Please note that this function is being also called in case of a bad
+ // fd to reset the main loop.
#ifdef HAVE_EPOLL
- epoll_fd = epoll_create(1);
- if (epoll_fd < 0)
- WRN("Failed to create epoll fd!");
+ pd->epoll_fd = epoll_create(1);
+ if (pd->epoll_fd < 0) WRN("Failed to create epoll fd!");
else
{
- eina_file_close_on_exec(epoll_fd, EINA_TRUE);
+ eina_file_close_on_exec(pd->epoll_fd, EINA_TRUE);
- epoll_pid = getpid();
+ pd->epoll_pid = getpid();
/* add polls on all our file descriptors */
Ecore_Fd_Handler *fdh;
- EINA_INLIST_FOREACH(fd_handlers, fdh)
+ EINA_INLIST_FOREACH(pd->fd_handlers, fdh)
{
if (fdh->delete_me) continue;
- _ecore_epoll_add(epoll_fd, fdh->fd,
+ _ecore_epoll_add(pd->epoll_fd, fdh->fd,
_ecore_poll_events_from_fdh(fdh), fdh);
- _ecore_main_fdh_poll_add(fdh);
+ _ecore_main_fdh_poll_add(pd, fdh);
}
}
#endif
-#ifdef HAVE_LIBUV
- {
- DBG("loading lib uv");
-#ifdef HAVE_NODEJS
- void* lib = dlopen(NULL, RTLD_LAZY);
-#else
- void* lib = dlopen("libuv.so", RTLD_GLOBAL | RTLD_LAZY);
-#endif
-
- if(lib && dlsym(lib, "uv_run"))
- {
- DBG("loaded lib uv");
- _dl_uv_run = dlsym(lib, "uv_run");
- assert(!!_dl_uv_run);
- _dl_uv_stop = dlsym(lib, "uv_stop");
- assert(!!_dl_uv_stop);
- _dl_uv_default_loop = dlsym(lib, "uv_default_loop");
- assert(!!_dl_uv_default_loop);
- _dl_uv_poll_init_socket = dlsym(lib, "uv_poll_init_socket");
- assert(!!_dl_uv_poll_init_socket);
- _dl_uv_poll_init = dlsym(lib, "uv_poll_init");
- assert(!!_dl_uv_poll_init);
- _dl_uv_poll_start = dlsym(lib, "uv_poll_start");
- assert(!!_dl_uv_poll_start);
- _dl_uv_poll_stop = dlsym(lib, "uv_poll_stop");
- assert(!!_dl_uv_poll_stop);
- _dl_uv_timer_init = dlsym(lib, "uv_timer_init");
- assert(!!_dl_uv_timer_init);
- _dl_uv_timer_start = dlsym(lib, "uv_timer_start");
- assert(!!_dl_uv_timer_start);
- _dl_uv_timer_stop = dlsym(lib, "uv_timer_stop");
- assert(!!_dl_uv_timer_stop);
- _dl_uv_prepare_init = dlsym(lib, "uv_prepare_init");
- assert(!!_dl_uv_prepare_init);
- _dl_uv_prepare_start = dlsym(lib, "uv_prepare_start");
- assert(!!_dl_uv_prepare_start);
- _dl_uv_prepare_stop = dlsym(lib, "uv_prepare_stop");
- assert(!!_dl_uv_prepare_stop);
- _dl_uv_check_init = dlsym(lib, "uv_check_init");
- assert(!!_dl_uv_check_init);
- _dl_uv_check_start = dlsym(lib, "uv_check_start");
- assert(!!_dl_uv_check_start);
- _dl_uv_check_stop = dlsym(lib, "uv_check_stop");
- assert(!!_dl_uv_check_stop);
- _dl_uv_close = dlsym(lib, "uv_close");
- assert(!!_dl_uv_close);
- _dl_uv_loop_alive = dlsym(lib, "uv_loop_alive");
- assert(!!_dl_uv_loop_alive);
-
- //dlclose(lib);
-
- DBG("_dl_uv_prepare_init");
- _dl_uv_prepare_init(_dl_uv_default_loop(), &_ecore_main_uv_prepare);
- DBG("_dl_uv_prepare_start");
- _dl_uv_prepare_start(&_ecore_main_uv_prepare, &_ecore_main_loop_uv_prepare);
- DBG("_dl_uv_prepare_started");
-
- DBG("_dl_uv_check_init");
- _dl_uv_check_init(_dl_uv_default_loop(), &_ecore_main_uv_check);
- DBG("_dl_uv_check_start");
- _dl_uv_check_start(&_ecore_main_uv_check, &_ecore_main_loop_uv_check);
- DBG("_dl_uv_check_started");
-
- _dl_uv_timer_init(_dl_uv_default_loop(), &_ecore_main_uv_handle_timers);
- }
- /* else */
- /* DBG("did not load uv"); */
- DBG("loaded dlsyms uv");
- }
-#endif
-
- /* setup for the g_main_loop only integration */
-#ifdef USE_G_MAIN_LOOP
- ecore_glib_source = g_source_new(&ecore_gsource_funcs, sizeof (GSource));
- if (!ecore_glib_source)
- CRI("Failed to create glib source for epoll!");
- else
+ if (obj == ML_OBJ)
{
- g_source_set_priority(ecore_glib_source, G_PRIORITY_HIGH_IDLE + 20);
-#ifdef HAVE_EPOLL
- if (epoll_fd >= 0)
+#ifdef HAVE_LIBUV
+ // XXX: FIXME: the below uv init should not assert but gracefully
+ // fail with errors
+ DBG("loading lib uv");
+# ifdef HAVE_NODEJS
+ void *lib = dlopen(NULL, RTLD_LAZY);
+# else
+ void *lib = dlopen("libuv.so.1", RTLD_GLOBAL | RTLD_LAZY);
+# endif
+
+ if (lib && dlsym(lib, "uv_run"))
{
- /* epoll multiplexes fds into the g_main_loop */
- ecore_epoll_fd.fd = epoll_fd;
- ecore_epoll_fd.events = G_IO_IN;
- ecore_epoll_fd.revents = 0;
- g_source_add_poll(ecore_glib_source, &ecore_epoll_fd);
+ DBG("loaded lib uv");
+ _dl_uv_run = dlsym(lib, "uv_run");
+ assert(!!_dl_uv_run);
+ _dl_uv_stop = dlsym(lib, "uv_stop");
+ assert(!!_dl_uv_stop);
+ _dl_uv_default_loop = dlsym(lib, "uv_default_loop");
+ assert(!!_dl_uv_default_loop);
+ _dl_uv_poll_init_socket = dlsym(lib, "uv_poll_init_socket");
+ assert(!!_dl_uv_poll_init_socket);
+ _dl_uv_poll_init = dlsym(lib, "uv_poll_init");
+ assert(!!_dl_uv_poll_init);
+ _dl_uv_poll_start = dlsym(lib, "uv_poll_start");
+ assert(!!_dl_uv_poll_start);
+ _dl_uv_poll_stop = dlsym(lib, "uv_poll_stop");
+ assert(!!_dl_uv_poll_stop);
+ _dl_uv_timer_init = dlsym(lib, "uv_timer_init");
+ assert(!!_dl_uv_timer_init);
+ _dl_uv_timer_start = dlsym(lib, "uv_timer_start");
+ assert(!!_dl_uv_timer_start);
+ _dl_uv_timer_stop = dlsym(lib, "uv_timer_stop");
+ assert(!!_dl_uv_timer_stop);
+ _dl_uv_prepare_init = dlsym(lib, "uv_prepare_init");
+ assert(!!_dl_uv_prepare_init);
+ _dl_uv_prepare_start = dlsym(lib, "uv_prepare_start");
+ assert(!!_dl_uv_prepare_start);
+ _dl_uv_prepare_stop = dlsym(lib, "uv_prepare_stop");
+ assert(!!_dl_uv_prepare_stop);
+ _dl_uv_check_init = dlsym(lib, "uv_check_init");
+ assert(!!_dl_uv_check_init);
+ _dl_uv_check_start = dlsym(lib, "uv_check_start");
+ assert(!!_dl_uv_check_start);
+ _dl_uv_check_stop = dlsym(lib, "uv_check_stop");
+ assert(!!_dl_uv_check_stop);
+ _dl_uv_close = dlsym(lib, "uv_close");
+ assert(!!_dl_uv_close);
+ _dl_uv_loop_alive = dlsym(lib, "uv_loop_alive");
+ assert(!!_dl_uv_loop_alive);
+
+ //dlclose(lib);
+
+ DBG("_dl_uv_prepare_init");
+ _dl_uv_prepare_init(_dl_uv_default_loop(), &_ecore_main_uv_prepare);
+ DBG("_dl_uv_prepare_start");
+ _dl_uv_prepare_start(&_ecore_main_uv_prepare, &_ecore_main_loop_uv_prepare);
+ DBG("_dl_uv_prepare_started");
+
+ DBG("_dl_uv_check_init");
+ _dl_uv_check_init(_dl_uv_default_loop(), &_ecore_main_uv_check);
+ DBG("_dl_uv_check_start");
+ _dl_uv_check_start(&_ecore_main_uv_check, &_ecore_main_loop_uv_check);
+ DBG("_dl_uv_check_started");
+
+ _dl_uv_timer_init(_dl_uv_default_loop(), &_ecore_main_uv_handle_timers);
}
+ // else
+ // DBG("did not load uv");
+ DBG("loaded dlsyms uv");
#endif
- /* timerfd gives us better than millisecond accuracy in g_main_loop */
- timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
- if (timer_fd < 0)
- WRN("failed to create timer fd!");
+
+ // setup for the g_main_loop only integration
+#ifdef USE_G_MAIN_LOOP
+ ecore_glib_source = g_source_new(&ecore_gsource_funcs,
+ sizeof(GSource));
+ if (!ecore_glib_source) CRI("Failed to create glib source for epoll!");
else
{
- eina_file_close_on_exec(timer_fd, EINA_TRUE);
- ecore_timer_fd.fd = timer_fd;
- ecore_timer_fd.events = G_IO_IN;
- ecore_timer_fd.revents = 0;
- g_source_add_poll(ecore_glib_source, &ecore_timer_fd);
- }
+ g_source_set_priority(ecore_glib_source,
+ G_PRIORITY_HIGH_IDLE + 20);
+# ifdef HAVE_EPOLL
+ if (pd->epoll_fd >= 0)
+ {
+ // epoll multiplexes fds into the g_main_loop
+ ecore_epoll_fd.fd = pd->epoll_fd;
+ ecore_epoll_fd.events = G_IO_IN;
+ ecore_epoll_fd.revents = 0;
+ g_source_add_poll(ecore_glib_source, &ecore_epoll_fd);
+ }
+# endif
+ // timerfd gives us better than millisecond accuracy
+ pd->timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
+ if (pd->timer_fd < 0) WRN("failed to create timer fd!");
+ else
+ {
+ eina_file_close_on_exec(pd->timer_fd, EINA_TRUE);
+ ecore_timer_fd.fd = pd->timer_fd;
+ ecore_timer_fd.events = G_IO_IN;
+ ecore_timer_fd.revents = 0;
+ g_source_add_poll(ecore_glib_source, &ecore_timer_fd);
+ }
- ecore_glib_source_id = g_source_attach(ecore_glib_source, NULL);
- if (ecore_glib_source_id <= 0)
- CRI("Failed to attach glib source to default context");
- }
+ ecore_glib_source_id = g_source_attach(ecore_glib_source, NULL);
+ if (ecore_glib_source_id <= 0)
+ CRI("Failed to attach glib source to default context");
+ }
#endif
-
- detect_time_changes_start();
+ }
+ _ecore_main_timechanges_start(obj);
}
-void
-_ecore_main_loop_shutdown(void)
+static void
+_ecore_main_loop_clear(Eo *obj, Efl_Loop_Data *pd)
{
- // Please note that _ecore_main_loop_shutdown is called in cycle to restart the main loop in case of a bad fd
-
-#ifdef USE_G_MAIN_LOOP
- if (ecore_glib_source)
+ if (!pd) return;
+ // Please note that _ecore_main_loop_shutdown is called in cycle to
+ // restart the main loop in case of a bad fd
+ if (obj == ML_OBJ)
{
- g_source_destroy(ecore_glib_source);
- ecore_glib_source = NULL;
- }
+ _ecore_main_timechanges_stop(obj);
+#ifdef USE_G_MAIN_LOOP
+ if (ecore_glib_source)
+ {
+ g_source_destroy(ecore_glib_source);
+ ecore_glib_source = NULL;
+ }
#endif
-
- detect_time_changes_stop();
-
-#ifdef HAVE_EPOLL
- if (epoll_fd >= 0)
- {
- close(epoll_fd);
- epoll_fd = -1;
- }
- epoll_pid = 0;
+#ifdef HAVE_LIBUV
+ if (_dl_uv_run)
+ {
+ DBG("_ecore_main_loop_shutdown");
+ _dl_uv_timer_stop(&_ecore_main_uv_handle_timers);
+ _dl_uv_close((uv_handle_t*)&_ecore_main_uv_handle_timers, 0);
+ }
#endif
-
- if (timer_fd >= 0)
+ }
+#ifdef HAVE_EPOLL
+ if (pd->epoll_fd >= 0)
{
- close(timer_fd);
- timer_fd = -1;
+ close(pd->epoll_fd);
+ pd->epoll_fd = -1;
}
-
-#ifdef HAVE_LIBUV
- if(_dl_uv_run)
+ if (pd->timer_fd >= 0)
{
- DBG("_ecore_main_loop_shutdown");
- _dl_uv_timer_stop(&_ecore_main_uv_handle_timers);
- _dl_uv_close((uv_handle_t*)&_ecore_main_uv_handle_timers, 0);
+ close(pd->timer_fd);
+ pd->timer_fd = -1;
}
#endif
}
-void *
-_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
+void
+_ecore_main_loop_init(void)
{
- DBG("_ecore_main_fd_handler_del %p", fd_handler);
- if (fd_handler->delete_me)
- {
- ERR("fdh %p deleted twice", fd_handler);
- return NULL;
- }
+ DBG("_ecore_main_loop_init");
+ if (!ecore_main_loop_get()) ERR("Cannot create main loop object");
+ _ecore_main_loop_setup(ML_OBJ, ML_DAT);
+}
- fd_handler->delete_me = EINA_TRUE;
- _ecore_main_fdh_poll_del(fd_handler);
- fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fd_handler);
- if (fd_handler->prep_func && fd_handlers_with_prep)
- fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fd_handler);
- if (fd_handler->buf_func && fd_handlers_with_buffer)
- fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fd_handler);
- return fd_handler->data;
+void
+_ecore_main_loop_shutdown(void)
+{
+ if (!ML_OBJ) return;
+ _ecore_main_loop_clear(ML_OBJ, ML_DAT);
+// XXX: this seemingly closes fd's it shouldn't.... :( fd 0?
+// efl_del(ML_OBJ);
+ ML_OBJ = NULL;
+ ML_DAT = NULL;
}
-EAPI void
-ecore_main_loop_iterate(void)
+void
+_ecore_main_loop_iterate(Eo *obj, Efl_Loop_Data *pd)
{
- EINA_MAIN_LOOP_CHECK_RETURN;
+ if (obj == ML_OBJ)
+ {
#ifdef HAVE_LIBUV
- if(!_dl_uv_run) {
+ if (!_dl_uv_run)
+ {
#endif
#ifndef USE_G_MAIN_LOOP
- _ecore_time_loop_time = ecore_time_get();
- _ecore_main_loop_iterate_internal(1);
+ pd->loop_time = ecore_time_get();
+ _ecore_main_loop_iterate_internal(obj, pd, 1);
#else
- g_main_context_iteration(NULL, 0);
+ g_main_context_iteration(NULL, 0);
#endif
#ifdef HAVE_LIBUV
- }
- else
- _dl_uv_run(_dl_uv_default_loop(), UV_RUN_ONCE | UV_RUN_NOWAIT);
+ }
+ else
+ _dl_uv_run(_dl_uv_default_loop(), UV_RUN_ONCE | UV_RUN_NOWAIT);
#endif
+ }
+ else
+ {
+ pd->loop_time = ecore_time_get();
+ _ecore_main_loop_iterate_internal(obj, pd, 1);
+ }
}
-EAPI int
-ecore_main_loop_iterate_may_block(int may_block)
+int
+_ecore_main_loop_iterate_may_block(Eo *obj, Efl_Loop_Data *pd, int may_block)
{
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
+ if (obj == ML_OBJ)
+ {
#ifdef HAVE_LIBUV
- if(!_dl_uv_run) {
+ if (!_dl_uv_run)
+ {
#endif
#ifndef USE_G_MAIN_LOOP
- _ecore_time_loop_time = ecore_time_get();
-in_main_loop++;
- _ecore_main_loop_iterate_internal(!may_block);
-in_main_loop--;
- return _ecore_event_exist();
+ in_main_loop++;
+ pd->in_loop = in_main_loop;
+ pd->loop_time = ecore_time_get();
+ _ecore_main_loop_iterate_internal(obj, pd, !may_block);
+ in_main_loop--;
+ pd->in_loop = in_main_loop;
+ return efl_loop_message_exists(obj);
#else
- return g_main_context_iteration(NULL, may_block);
+ return g_main_context_iteration(NULL, may_block);
#endif
#ifdef HAVE_LIBUV
- }
- else
- _dl_uv_run(_dl_uv_default_loop(), may_block ? UV_RUN_ONCE | UV_RUN_NOWAIT : UV_RUN_ONCE);
+ }
+ else
+ _dl_uv_run(_dl_uv_default_loop(),
+ may_block ? (UV_RUN_ONCE | UV_RUN_NOWAIT) : UV_RUN_ONCE);
#endif
+ }
+ else
+ {
+ pd->in_loop++;
+ pd->loop_time = ecore_time_get();
+ _ecore_main_loop_iterate_internal(obj, pd, !may_block);
+ pd->in_loop--;
+ return efl_loop_message_exists(obj);
+ }
return 0;
}
-EAPI void
-ecore_main_loop_begin(void)
+void
+_ecore_main_loop_begin(Eo *obj, Efl_Loop_Data *pd)
{
- DBG("ecore_main_loop_begin");
- EINA_MAIN_LOOP_CHECK_RETURN;
- if (in_main_loop > 0)
+ if (obj == ML_OBJ)
{
- ERR("Running ecore_main_loop_begin() inside an existing main loop");
- return;
- }
- eina_evlog("+mainloop", NULL, 0.0, NULL);
+ if (pd->in_loop > 0)
+ {
+ ERR("Beginning main loop() inside an existing main loop");
+ return;
+ }
#ifdef HAVE_SYSTEMD
- sd_notify(0, "READY=1");
+ sd_notify(0, "READY=1");
#endif
#ifdef HAVE_LIBUV
- if(!_dl_uv_run) {
+ if (!_dl_uv_run)
+ {
#endif
#ifndef USE_G_MAIN_LOOP
- in_main_loop++;
- _ecore_time_loop_time = ecore_time_get();
- while (do_quit == 0) _ecore_main_loop_iterate_internal(0);
- do_quit = 0;
- in_main_loop--;
+ in_main_loop++;
+ pd->in_loop = in_main_loop;
+ pd->loop_time = ecore_time_get();
+ while (!pd->do_quit)
+ _ecore_main_loop_iterate_internal(obj, pd, 0);
+ pd->do_quit = 0;
+ in_main_loop--;
+ pd->in_loop = in_main_loop;
#else
- if (!do_quit)
- {
- if (!ecore_main_loop)
- ecore_main_loop = g_main_loop_new(NULL, FALSE);
- g_main_loop_run(ecore_main_loop);
- }
- do_quit = 0;
+ if (!pd->do_quit)
+ {
+ if (!ecore_main_loop)
+ ecore_main_loop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(ecore_main_loop);
+ }
+ pd->do_quit = 0;
#endif
#ifdef HAVE_LIBUV
- }
+ }
+ else
+ {
+ DBG("uv_run");
+ in_main_loop++;
+ pd->in_loop = in_main_loop;
+ pd->loop_time = ecore_time_get();
+ while (!pd->do_quit)
+ _dl_uv_run(_dl_uv_default_loop(), UV_RUN_DEFAULT);
+ in_main_loop--;
+ pd->in_loop = in_main_loop;
+ pd->do_quit = 0;
+ DBG("quit");
+ }
+#endif
+ }
else
{
- DBG("uv_run");
- _ecore_time_loop_time = ecore_time_get();
- in_main_loop++;
- while(!do_quit)
- _dl_uv_run(_dl_uv_default_loop(), UV_RUN_DEFAULT);
- in_main_loop--;
- do_quit = 0;
- DBG("quit");
+ pd->in_loop++;
+ pd->loop_time = ecore_time_get();
+ while (!pd->do_quit)
+ _ecore_main_loop_iterate_internal(obj, pd, 0);
+ pd->do_quit = 0;
+ pd->in_loop--;
}
+}
+
+void
+_ecore_main_loop_quit(Eo *obj, Efl_Loop_Data *pd)
+{
+ pd->do_quit = 1;
+ if (obj != ML_OBJ) return;
+#ifdef USE_G_MAIN_LOOP
+ if (ecore_main_loop) g_main_loop_quit(ecore_main_loop);
+#elif defined(HAVE_LIBUV)
+ if (_dl_uv_run) _dl_uv_stop(_dl_uv_default_loop());
#endif
+}
+
+EAPI void
+ecore_main_loop_iterate(void)
+{
+ EINA_MAIN_LOOP_CHECK_RETURN;
+ efl_loop_iterate(ML_OBJ);
+}
+
+EAPI int
+ecore_main_loop_iterate_may_block(int may_block)
+{
+ EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
+ return efl_loop_iterate_may_block(ML_OBJ, may_block);
+}
+
+EAPI void
+ecore_main_loop_begin(void)
+{
+ DBG("ecore_main_loop_begin");
+ EINA_MAIN_LOOP_CHECK_RETURN;
+ eina_evlog("+mainloop", NULL, 0.0, NULL);
+ efl_loop_begin(ML_OBJ);
eina_evlog("-mainloop", NULL, 0.0, NULL);
}
EAPI void
ecore_main_loop_quit(void)
{
+ Eina_Value v = EINA_VALUE_EMPTY;
+ int val = 0;
+
+ eina_value_setup(&v, EINA_VALUE_TYPE_INT);
+ eina_value_set(&v, &val);
EINA_MAIN_LOOP_CHECK_RETURN;
- do_quit = 1;
-#ifdef USE_G_MAIN_LOOP
- if (ecore_main_loop)
- g_main_loop_quit(ecore_main_loop);
-#elif defined(HAVE_LIBUV)
- if (_dl_uv_run)
- _dl_uv_stop(_dl_uv_default_loop());
-#endif
+ efl_loop_quit(ML_OBJ, v);
}
-EAPI int
+EAPI int
ecore_main_loop_nested_get(void)
{
return in_main_loop;
@@ -1381,7 +1259,10 @@ ecore_main_loop_select_func_get(void)
}
Ecore_Fd_Handler *
-_ecore_main_fd_handler_add(int fd,
+_ecore_main_fd_handler_add(Eo *obj,
+ Efl_Loop_Data *pd,
+ Eo *handler,
+ int fd,
Ecore_Fd_Handler_Flags flags,
Ecore_Fd_Cb func,
const void *data,
@@ -1397,36 +1278,63 @@ _ecore_main_fd_handler_add(int fd,
fdh = ecore_fd_handler_calloc(1);
if (!fdh) return NULL;
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
- fdh->next_ready = NULL;
+ fdh->loop = obj;
+ fdh->loop_data = pd;
+ fdh->handler = handler;
fdh->fd = fd;
fdh->flags = flags;
fdh->file = is_file;
- if (_ecore_main_fdh_poll_add(fdh) < 0)
+ if (_ecore_main_fdh_poll_add(pd, fdh) < 0)
{
int err = errno;
- ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err));
+ ERR("Failed to add poll on fd %d (errno = %d: %s)!",
+ fd, err, strerror(err));
ecore_fd_handler_mp_free(fdh);
return NULL;
}
- fdh->read_active = EINA_FALSE;
- fdh->write_active = EINA_FALSE;
- fdh->error_active = EINA_FALSE;
- fdh->delete_me = EINA_FALSE;
fdh->func = func;
fdh->data = (void *)data;
fdh->buf_func = buf_func;
if (buf_func)
- fd_handlers_with_buffer = eina_list_append(fd_handlers_with_buffer, fdh);
+ pd->fd_handlers_with_buffer = eina_list_append
+ (pd->fd_handlers_with_buffer, fdh);
fdh->buf_data = (void *)buf_data;
if (is_file)
- file_fd_handlers = eina_list_append(file_fd_handlers, fdh);
- fd_handlers = (Ecore_Fd_Handler *)
- eina_inlist_append(EINA_INLIST_GET(fd_handlers),
+ pd->file_fd_handlers = eina_list_append
+ (pd->file_fd_handlers, fdh);
+ pd->fd_handlers = (Ecore_Fd_Handler *)
+ eina_inlist_append(EINA_INLIST_GET(pd->fd_handlers),
EINA_INLIST_GET(fdh));
return fdh;
}
+void *
+_ecore_main_fd_handler_del(Eo *obj EINA_UNUSED,
+ Efl_Loop_Data *pd,
+ Ecore_Fd_Handler *fd_handler)
+{
+ DBG("_ecore_main_fd_handler_del %p", fd_handler);
+ if (fd_handler->delete_me)
+ {
+ ERR("fdh %p deleted twice", fd_handler);
+ return NULL;
+ }
+
+ fd_handler->handler = NULL;
+ fd_handler->delete_me = EINA_TRUE;
+ _ecore_main_fdh_poll_del(pd, fd_handler);
+ pd->fd_handlers_to_delete = eina_list_append
+ (pd->fd_handlers_to_delete, fd_handler);
+ if (fd_handler->prep_func && pd->fd_handlers_with_prep)
+ pd->fd_handlers_with_prep = eina_list_remove
+ (pd->fd_handlers_with_prep, fd_handler);
+ if (fd_handler->buf_func && pd->fd_handlers_with_buffer)
+ pd->fd_handlers_with_buffer = eina_list_remove
+ (pd->fd_handlers_with_buffer, fd_handler);
+ return fd_handler->data;
+}
+
EAPI Ecore_Fd_Handler *
ecore_main_fd_handler_add(int fd,
Ecore_Fd_Handler_Flags flags,
@@ -1437,7 +1345,9 @@ ecore_main_fd_handler_add(int fd,
{
Ecore_Fd_Handler *fdh = NULL;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- fdh = _ecore_main_fd_handler_add(fd, flags, func, data, buf_func, buf_data, EINA_FALSE);
+ fdh = _ecore_main_fd_handler_add(efl_loop_main_get(EFL_LOOP_CLASS),
+ ML_DAT, NULL, fd, flags, func, data,
+ buf_func, buf_data, EINA_FALSE);
return fdh;
}
@@ -1450,15 +1360,36 @@ ecore_main_fd_handler_file_add(int fd,
const void *buf_data)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- return _ecore_main_fd_handler_add(fd, flags, func, data, buf_func, buf_data, EINA_TRUE);
+ return _ecore_main_fd_handler_add(efl_loop_main_get(EFL_LOOP_CLASS),
+ ML_DAT, NULL, fd, flags, func, data,
+ buf_func, buf_data, EINA_TRUE);
+}
+
+EAPI void *
+ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
+{
+ if (!fd_handler) return NULL;
+ EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
+
+ if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
+ {
+ ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
+ "ecore_main_fd_handler_del");
+ return NULL;
+ }
+ return _ecore_main_fd_handler_del(ML_OBJ, ML_DAT, fd_handler);
}
#ifdef _WIN32
EAPI Ecore_Win32_Handler *
-ecore_main_win32_handler_add(void *h,
- Ecore_Win32_Handle_Cb func,
- const void *data)
-{
+_ecore_main_win32_handler_add(Eo *obj,
+ Efl_Loop_Data *pd,
+ Eo *handler,
+ void *h,
+ Ecore_Win32_Handle_Cb func,
+ const void *data)
+{
+ Efl_Loop_Data *pd = ML_DAT;
Ecore_Win32_Handler *wh;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
@@ -1467,45 +1398,19 @@ ecore_main_win32_handler_add(void *h,
wh = ecore_win32_handler_calloc(1);
if (!wh) return NULL;
ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER);
+ wh->loop = obj;
+ wh->loop_data = pd;
wh->h = (HANDLE)h;
- wh->delete_me = EINA_FALSE;
wh->func = func;
wh->data = (void *)data;
- win32_handlers = (Ecore_Win32_Handler *)
- eina_inlist_append(EINA_INLIST_GET(win32_handlers),
+ pd->win32_handlers = (Ecore_Win32_Handler *)
+ eina_inlist_append(EINA_INLIST_GET(pd->win32_handlers),
EINA_INLIST_GET(wh));
return wh;
}
-#else
-EAPI Ecore_Win32_Handler *
-ecore_main_win32_handler_add(void *h EINA_UNUSED,
- Ecore_Win32_Handle_Cb func EINA_UNUSED,
- const void *data EINA_UNUSED)
-{
- return NULL;
-}
-
-#endif
-
-EAPI void *
-ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
-{
- if (!fd_handler) return NULL;
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
-
- if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
- {
- ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
- "ecore_main_fd_handler_del");
- return NULL;
- }
- return _ecore_main_fd_handler_del(fd_handler);
-}
-
-#ifdef _WIN32
-static void *
-_ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler)
+void *
+_ecore_main_win32_handler_del(Eo *obj, Efl_Loop_Data *pd, Ecore_Win32_Handler *win32_handler)
{
if (win32_handler->delete_me)
{
@@ -1514,10 +1419,22 @@ _ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler)
}
win32_handler->delete_me = EINA_TRUE;
- win32_handlers_to_delete = eina_list_append(win32_handlers_to_delete, win32_handler);
+ win32_handler->handler = NULL;
+ pd->win32_handlers_to_delete = eina_list_append
+ (pd->win32_handlers_to_delete, win32_handler);
return win32_handler->data;
}
+EAPI Ecore_Win32_Handler *
+ecore_main_win32_handler_add(void *h,
+ Ecore_Win32_Handle_Cb func,
+ const void *data)
+{
+ EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
+ return _ecore_main_win32_handler_add(efl_loop_main_get(EFL_LOOP_CLASS),
+ ML_DAT, NULL, func, data);
+}
+
EAPI void *
ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler)
{
@@ -1531,17 +1448,42 @@ ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler)
"ecore_main_win32_handler_del");
return NULL;
}
- ret = _ecore_main_win32_handler_del(win32_handler);
+ ret = _ecore_main_win32_handler_del(ML_OBJ, ML_DAT, win32_handler);
return ret;
}
-
#else
+EAPI Ecore_Win32_Handler *
+_ecore_main_win32_handler_add(Eo *obj EINA_UNUSED,
+ Efl_Loop_Data *pd EINA_UNUSED,
+ Eo *handler EINA_UNUSED,
+ void *h EINA_UNUSED,
+ Ecore_Win32_Handle_Cb func EINA_UNUSED,
+ const void *data EINA_UNUSED)
+{
+ return NULL;
+}
+
+void *
+_ecore_main_win32_handler_del(Eo *obj EINA_UNUSED,
+ Efl_Loop_Data *pd EINA_UNUSED,
+ Ecore_Win32_Handler *win32_handler EINA_UNUSED)
+{
+ return NULL;
+}
+
+EAPI Ecore_Win32_Handler *
+ecore_main_win32_handler_add(void *h EINA_UNUSED,
+ Ecore_Win32_Handle_Cb func EINA_UNUSED,
+ const void *data EINA_UNUSED)
+{
+ return NULL;
+}
+
EAPI void *
ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler EINA_UNUSED)
{
return NULL;
}
-
#endif
EAPI void
@@ -1549,20 +1491,23 @@ ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler,
Ecore_Fd_Prep_Cb func,
const void *data)
{
+ Efl_Loop_Data *pd = fd_handler->loop_data;
EINA_MAIN_LOOP_CHECK_RETURN;
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
{
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
"ecore_main_fd_handler_prepare_callback_set");
- return ;
+ return;
}
fd_handler->prep_func = func;
fd_handler->prep_data = (void *)data;
- if ((!fd_handlers_with_prep) ||
- (fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler))))
- /* FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! */
- fd_handlers_with_prep = eina_list_append(fd_handlers_with_prep, fd_handler);
+ if ((!pd->fd_handlers_with_prep) ||
+ (pd->fd_handlers_with_prep &&
+ (!eina_list_data_find(pd->fd_handlers_with_prep, fd_handler))))
+ // FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!!
+ pd->fd_handlers_with_prep = eina_list_append
+ (pd->fd_handlers_with_prep, fd_handler);
}
EAPI int
@@ -1593,7 +1538,7 @@ ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler,
"ecore_main_fd_handler_active_get");
return EINA_FALSE;
}
- if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE;
+ if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE;
if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE;
if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE;
return ret;
@@ -1603,99 +1548,117 @@ EAPI void
ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler,
Ecore_Fd_Handler_Flags flags)
{
- int ret;
-
- EINA_MAIN_LOOP_CHECK_RETURN;
+ int ret = -1;
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
{
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
"ecore_main_fd_handler_active_set");
- return ;
+ return;
}
fd_handler->flags = flags;
- ret = _ecore_main_fdh_poll_modify(fd_handler);
+ if (fd_handler->loop_data)
+ ret = _ecore_main_fdh_poll_modify(fd_handler->loop_data, fd_handler);
if (ret < 0)
- {
- ERR("Failed to mod epoll fd %d: %s!", fd_handler->fd, strerror(errno));
- }
+ ERR("Failed to mod epoll fd %d, loop data=%p: %s!",
+ fd_handler->fd, fd_handler->loop_data, strerror(errno));
}
void
-_ecore_main_shutdown(void)
+_ecore_main_content_clear(Efl_Loop_Data *pd)
{
Efl_Promise *promise;
Efl_Future *future;
- if (in_main_loop)
- {
- ERR("\n"
- "*** ECORE WARNING: Calling ecore_shutdown() while still in the main loop.\n"
- "*** Program may crash or behave strangely now.");
- return;
- }
-
- EINA_LIST_FREE(_pending_futures, future)
+ EINA_LIST_FREE(pd->pending_futures, future)
efl_del(future);
-
- EINA_LIST_FREE(_pending_promises, promise)
+ Eina_List *tmp = pd->pending_promises;
+ pd->pending_promises = NULL;
+ EINA_LIST_FREE(tmp, promise)
ecore_loop_promise_fulfill(promise);
- while (fd_handlers)
+ while (pd->fd_handlers)
{
- Ecore_Fd_Handler *fdh;
+ Ecore_Fd_Handler *fdh = pd->fd_handlers;
- fdh = fd_handlers;
- fd_handlers = (Ecore_Fd_Handler *)eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
- EINA_INLIST_GET(fdh));
- ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
- ecore_fd_handler_mp_free(fdh);
+ pd->fd_handlers = (Ecore_Fd_Handler *)
+ eina_inlist_remove(EINA_INLIST_GET(pd->fd_handlers),
+ EINA_INLIST_GET(fdh));
+ if (fdh->handler) efl_del(fdh->handler);
+ else
+ {
+ ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
+ ecore_fd_handler_mp_free(fdh);
+ }
+ }
+ if (pd)
+ {
+ if (pd->fd_handlers_with_buffer)
+ pd->fd_handlers_with_buffer =
+ eina_list_free(pd->fd_handlers_with_buffer);
+ if (pd->fd_handlers_with_prep)
+ pd->fd_handlers_with_prep =
+ eina_list_free(pd->fd_handlers_with_prep);
+ if (pd->file_fd_handlers)
+ pd->file_fd_handlers =
+ eina_list_free(pd->file_fd_handlers);
+ if (pd->fd_handlers_to_delete)
+ pd->fd_handlers_to_delete =
+ eina_list_free(pd->fd_handlers_to_delete);
+ pd->fd_handlers_to_call = NULL;
+ pd->fd_handlers_to_call_current = NULL;
}
- if (fd_handlers_with_buffer)
- fd_handlers_with_buffer = eina_list_free(fd_handlers_with_buffer);
- if (fd_handlers_with_prep)
- fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep);
- if (fd_handlers_to_delete)
- fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete);
- if (file_fd_handlers)
- file_fd_handlers = eina_list_free(file_fd_handlers);
-
- fd_handlers_to_call = NULL;
- fd_handlers_to_call_current = NULL;
- fd_handlers_to_delete = NULL;
- fd_handler_current = NULL;
- do_quit = 0;
+
+ pd->do_quit = 0;
#ifdef _WIN32
- while (win32_handlers)
+ while (pd->win32_handlers)
{
- Ecore_Win32_Handler *wh;
+ Ecore_Win32_Handler *wh = pd->win32_handlers;
- wh = win32_handlers;
- win32_handlers = (Ecore_Win32_Handler *)eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
- EINA_INLIST_GET(wh));
- ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
- ecore_win32_handler_mp_free(wh);
+ pd->win32_handlers = (Ecore_Win32_Handler *)
+ eina_inlist_remove(EINA_INLIST_GET(pd->win32_handlers),
+ EINA_INLIST_GET(wh));
+ if (fdh->handler) efl_del(fdh->handler);
+ else
+ {
+ ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
+ ecore_win32_handler_mp_free(wh);
+ }
}
- if (win32_handlers_to_delete)
- win32_handlers_to_delete = eina_list_free(win32_handlers_to_delete);
- win32_handlers_to_delete = NULL;
- win32_handler_current = NULL;
+ if (pd->win32_handlers_to_delete)
+ pd->win32_handlers_to_delete =
+ eina_list_free(pd->win32_handlers_to_delete);
+ pd->win32_handler_current = NULL;
#endif
}
+void
+_ecore_main_shutdown(void)
+{
+ Efl_Loop_Data *pd = ML_DAT;
+
+ if (pd->in_loop)
+ {
+ ERR("Calling ecore_shutdown() while still in the main loop!!!");
+ return;
+ }
+ _ecore_main_content_clear(pd);
+}
+
static void
-_ecore_main_prepare_handlers(void)
+_ecore_main_prepare_handlers(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
{
Ecore_Fd_Handler *fdh;
Eina_List *l, *l2;
- /* call the prepare callback for all handlers with prep functions */
- EINA_LIST_FOREACH_SAFE(fd_handlers_with_prep, l, l2, fdh)
+ // call the prepare callback for all handlers with prep functions
+ EINA_LIST_FOREACH_SAFE(pd->fd_handlers_with_prep, l, l2, fdh)
{
if (!fdh)
{
- fd_handlers_with_prep = eina_list_remove_list(l, fd_handlers_with_prep);
+ pd->fd_handlers_with_prep = eina_list_remove_list
+ (l, pd->fd_handlers_with_prep);
continue;
}
if (!fdh->delete_me && fdh->prep_func)
@@ -1705,13 +1668,14 @@ _ecore_main_prepare_handlers(void)
fdh->references--;
}
else
- fd_handlers_with_prep = eina_list_remove_list(fd_handlers_with_prep, l);
+ pd->fd_handlers_with_prep = eina_list_remove_list
+ (pd->fd_handlers_with_prep, l);
}
}
#if !defined(USE_G_MAIN_LOOP)
static int
-_ecore_main_select(double timeout)
+_ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
{
struct timeval tv, *t;
fd_set rfds, wfds, exfds;
@@ -1720,8 +1684,8 @@ _ecore_main_select(double timeout)
int max_fd, ret, err_no;
t = NULL;
- if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0))) /* finite() tests for NaN, too big, too small, and infinity. */
- {
+ if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0)))
+ { // finite() tests for NaN, too big, too small, and infinity.
tv.tv_sec = 0;
tv.tv_usec = 0;
t = &tv;
@@ -1747,15 +1711,14 @@ _ecore_main_select(double timeout)
FD_ZERO(&wfds);
FD_ZERO(&exfds);
- /* call the prepare callback for all handlers */
- if (fd_handlers_with_prep)
- _ecore_main_prepare_handlers();
+ // call the prepare callback for all handlers
+ if (pd->fd_handlers_with_prep) _ecore_main_prepare_handlers(obj, pd);
#ifdef HAVE_EPOLL
- if (epoll_fd < 0)
+ if (pd->epoll_fd < 0)
{
#endif
- EINA_INLIST_FOREACH(fd_handlers, fdh)
+ EINA_INLIST_FOREACH(pd->fd_handlers, fdh)
{
if (!fdh->delete_me)
{
@@ -1780,87 +1743,91 @@ _ecore_main_select(double timeout)
#ifdef HAVE_EPOLL
else
{
- /* polling on the epoll fd will wake when an fd in the epoll set is active */
- max_fd = _ecore_get_epoll_fd();
- FD_SET(max_fd, &rfds);
- }
-#endif
- EINA_LIST_FOREACH(file_fd_handlers, l, fdh)
- if (!fdh->delete_me)
- {
- if (fdh->flags & ECORE_FD_READ)
- {
- FD_SET(fdh->fd, &rfds);
- if (fdh->fd > max_fd) max_fd = fdh->fd;
- }
- if (fdh->flags & ECORE_FD_WRITE)
- {
- FD_SET(fdh->fd, &wfds);
- if (fdh->fd > max_fd) max_fd = fdh->fd;
- }
- if (fdh->flags & ECORE_FD_ERROR)
- {
- FD_SET(fdh->fd, &exfds);
- if (fdh->fd > max_fd) max_fd = fdh->fd;
- }
- if (fdh->fd > max_fd) max_fd = fdh->fd;
- }
- if (_ecore_signal_count_get()) return -1;
+ // polling on the epoll fd will wake when fd in the epoll set is active
+ max_fd = _ecore_get_epoll_fd(obj, pd);
+ FD_SET(max_fd, &rfds);
+ }
+#endif
+ EINA_LIST_FOREACH(pd->file_fd_handlers, l, fdh)
+ {
+ if (!fdh->delete_me)
+ {
+ if (fdh->flags & ECORE_FD_READ)
+ {
+ FD_SET(fdh->fd, &rfds);
+ if (fdh->fd > max_fd) max_fd = fdh->fd;
+ }
+ if (fdh->flags & ECORE_FD_WRITE)
+ {
+ FD_SET(fdh->fd, &wfds);
+ if (fdh->fd > max_fd) max_fd = fdh->fd;
+ }
+ if (fdh->flags & ECORE_FD_ERROR)
+ {
+ FD_SET(fdh->fd, &exfds);
+ if (fdh->fd > max_fd) max_fd = fdh->fd;
+ }
+ if (fdh->fd > max_fd) max_fd = fdh->fd;
+ }
+ }
+ if (_ecore_signal_count_get(obj, pd)) return -1;
eina_evlog("<RUN", NULL, 0.0, NULL);
eina_evlog("!SLEEP", NULL, 0.0, t ? "timeout" : "forever");
- ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
+ if (obj == ML_OBJ)
+ ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
+ else
+ ret = general_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
err_no = errno;
eina_evlog("!WAKE", NULL, 0.0, NULL);
eina_evlog(">RUN", NULL, 0.0, NULL);
- _ecore_time_loop_time = ecore_time_get();
+ pd->loop_time = ecore_time_get();
if (ret < 0)
{
#ifndef _WIN32
if (err_no == EINTR) return -1;
- else if (err_no == EBADF)
- _ecore_main_fd_handlers_bads_rem();
+ else if (err_no == EBADF) _ecore_main_fd_handlers_bads_rem(obj, pd);
#endif
}
if (ret > 0)
{
#ifdef HAVE_EPOLL
- if (epoll_fd >= 0)
- _ecore_main_fdh_epoll_mark_active();
+ if (pd->epoll_fd >= 0)
+ _ecore_main_fdh_epoll_mark_active(obj, pd);
else
#endif
{
- EINA_INLIST_FOREACH(fd_handlers, fdh)
+ EINA_INLIST_FOREACH(pd->fd_handlers, fdh)
{
if (!fdh->delete_me)
{
if (FD_ISSET(fdh->fd, &rfds))
- fdh->read_active = EINA_TRUE;
+ fdh->read_active = EINA_TRUE;
if (FD_ISSET(fdh->fd, &wfds))
fdh->write_active = EINA_TRUE;
if (FD_ISSET(fdh->fd, &exfds))
fdh->error_active = EINA_TRUE;
- _ecore_try_add_to_call_list(fdh);
+ _ecore_try_add_to_call_list(obj, pd, fdh);
}
}
}
- EINA_LIST_FOREACH(file_fd_handlers, l, fdh)
+ EINA_LIST_FOREACH(pd->file_fd_handlers, l, fdh)
{
if (!fdh->delete_me)
{
if (FD_ISSET(fdh->fd, &rfds))
- fdh->read_active = EINA_TRUE;
+ fdh->read_active = EINA_TRUE;
if (FD_ISSET(fdh->fd, &wfds))
fdh->write_active = EINA_TRUE;
if (FD_ISSET(fdh->fd, &exfds))
fdh->error_active = EINA_TRUE;
- _ecore_try_add_to_call_list(fdh);
+ _ecore_try_add_to_call_list(obj, pd, fdh);
}
}
- _ecore_main_fd_handlers_cleanup();
+ _ecore_main_fd_handlers_cleanup(obj, pd);
#ifdef _WIN32
- _ecore_main_win32_handlers_cleanup();
+ _ecore_main_win32_handlers_cleanup(obj, pd);
#endif
return 1;
}
@@ -1872,14 +1839,14 @@ _ecore_main_select(double timeout)
#ifndef _WIN32
# ifndef USE_G_MAIN_LOOP
static void
-_ecore_main_fd_handlers_bads_rem(void)
+_ecore_main_fd_handlers_bads_rem(Eo *obj, Efl_Loop_Data *pd)
{
Ecore_Fd_Handler *fdh;
Eina_Inlist *l;
int found = 0;
ERR("Removing bad fds");
- for (l = EINA_INLIST_GET(fd_handlers); l; )
+ for (l = EINA_INLIST_GET(pd->fd_handlers); l; )
{
fdh = (Ecore_Fd_Handler *)l;
l = l->next;
@@ -1898,8 +1865,9 @@ _ecore_main_fd_handlers_bads_rem(void)
if (!fdh->delete_me)
{
fdh->delete_me = EINA_TRUE;
- _ecore_main_fdh_poll_del(fdh);
- fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
+ _ecore_main_fdh_poll_del(pd, fdh);
+ pd->fd_handlers_to_delete =
+ eina_list_append(pd->fd_handlers_to_delete, fdh);
}
found++;
}
@@ -1907,12 +1875,14 @@ _ecore_main_fd_handlers_bads_rem(void)
}
else
{
- ERR("Problematic fd found at %d! setting it for delete", fdh->fd);
+ ERR("Problematic fd found at %d! setting it for delete",
+ fdh->fd);
if (!fdh->delete_me)
{
fdh->delete_me = EINA_TRUE;
- _ecore_main_fdh_poll_del(fdh);
- fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
+ _ecore_main_fdh_poll_del(pd, fdh);
+ pd->fd_handlers_to_delete =
+ eina_list_append(pd->fd_handlers_to_delete, fdh);
}
found++;
@@ -1927,170 +1897,171 @@ _ecore_main_fd_handlers_bads_rem(void)
ERR("No bad fd found. EEEK!");
# endif
}
- _ecore_main_fd_handlers_cleanup();
+ _ecore_main_fd_handlers_cleanup(obj, pd);
}
# endif
#endif
static void
-_ecore_main_fd_handlers_cleanup(void)
+_ecore_main_fd_handlers_cleanup(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
{
Ecore_Fd_Handler *fdh, *last;
Eina_List *l, *l2;
- if (!fd_handlers_to_delete) return;
-
// Cleanup deleted caller from the list
last = NULL;
- fdh = fd_handlers_to_call;
+ fdh = pd->fd_handlers_to_call;
while (fdh)
{
if (fdh->delete_me)
{
if (!last)
- fd_handlers_to_call = fdh == fdh->next_ready ? NULL : fdh->next_ready;
+ pd->fd_handlers_to_call = fdh == fdh->next_ready ?
+ NULL : fdh->next_ready;
else
- last->next_ready = fdh == fdh->next_ready ? last : fdh->next_ready;
- }
- else
- {
- last = fdh;
+ last->next_ready = fdh == fdh->next_ready ?
+ last : fdh->next_ready;
}
+ else last = fdh;
- if (fdh == fdh->next_ready)
- break;
+ if (fdh == fdh->next_ready) break;
fdh = fdh->next_ready;
}
- EINA_LIST_FOREACH_SAFE(fd_handlers_to_delete, l, l2, fdh)
+ if (!pd->fd_handlers_to_delete) return;
+ EINA_LIST_FOREACH_SAFE(pd->fd_handlers_to_delete, l, l2, fdh)
{
if (!fdh)
{
- fd_handlers_to_delete = eina_list_remove_list(l, fd_handlers_to_delete);
+ pd->fd_handlers_to_delete = eina_list_remove_list
+ (l, pd->fd_handlers_to_delete);
continue;
}
- /* fdh->delete_me should be set for all fdhs at the start of the list */
- if (fdh->references)
- continue;
- if (fd_handlers_to_call_current == fdh)
- fd_handlers_to_call_current = NULL;
- if (fdh->buf_func && fd_handlers_with_buffer)
- fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fdh);
- if (fdh->prep_func && fd_handlers_with_prep)
- fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fdh);
- fd_handlers = (Ecore_Fd_Handler *)
- eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh));
+ if (fdh->references) continue;
+ if (pd->fd_handlers_to_call_current == fdh)
+ pd->fd_handlers_to_call_current = NULL;
+ if (fdh->buf_func && pd->fd_handlers_with_buffer)
+ pd->fd_handlers_with_buffer = eina_list_remove
+ (pd->fd_handlers_with_buffer, fdh);
+ if (fdh->prep_func && pd->fd_handlers_with_prep)
+ pd->fd_handlers_with_prep = eina_list_remove
+ (pd->fd_handlers_with_prep, fdh);
+ pd->fd_handlers = (Ecore_Fd_Handler *)
+ eina_inlist_remove(EINA_INLIST_GET(pd->fd_handlers),
+ EINA_INLIST_GET(fdh));
if (fdh->file)
- file_fd_handlers = eina_list_remove(file_fd_handlers, fdh);
+ pd->file_fd_handlers = eina_list_remove(pd->file_fd_handlers, fdh);
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
ecore_fd_handler_mp_free(fdh);
- fd_handlers_to_delete = eina_list_remove_list(fd_handlers_to_delete, l);
+ pd->fd_handlers_to_delete = eina_list_remove_list
+ (pd->fd_handlers_to_delete, l);
}
}
#ifdef _WIN32
static void
-_ecore_main_win32_handlers_cleanup(void)
+_ecore_main_win32_handlers_cleanup(Eo *obj, Efl_Loop_Data *pd)
{
Ecore_Win32_Handler *wh;
- Eina_List *l;
- Eina_List *l2;
+ Eina_List *l, *l2;
- if (!win32_handlers_to_delete) return;
- EINA_LIST_FOREACH_SAFE(win32_handlers_to_delete, l, l2, wh)
+ if (!pd->win32_handlers_to_delete) return;
+ EINA_LIST_FOREACH_SAFE(pd->win32_handlers_to_delete, l, l2, wh)
{
if (!wh)
{
- win32_handlers_to_delete = eina_list_remove_list(l, win32_handlers_to_delete);
+ pd->win32_handlers_to_delete = eina_list_remove_list
+ (l, pd->win32_handlers_to_delete);
continue;
}
- /* wh->delete_me should be set for all whs at the start of the list */
- if (wh->references)
- continue;
- win32_handlers = (Ecore_Win32_Handler *)
- eina_inlist_remove(EINA_INLIST_GET(win32_handlers), EINA_INLIST_GET(wh));
+ // wh->delete_me should be set for all whs at the start of the list
+ if (wh->references) continue;
+ pd->win32_handlers = (Ecore_Win32_Handler *)
+ eina_inlist_remove(EINA_INLIST_GET(pd->win32_handlers),
+ EINA_INLIST_GET(wh));
ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
ecore_win32_handler_mp_free(wh);
- win32_handlers_to_delete = eina_list_remove_list(win32_handlers_to_delete, l);
+ pd->win32_handlers_to_delete = eina_list_remove_list
+ (pd->win32_handlers_to_delete, l);
}
}
-
#endif
static void
-_ecore_main_fd_handlers_call(void)
+_ecore_main_fd_handlers_call(Eo *obj, Efl_Loop_Data *pd)
{
- /* grab a new list */
- if (!fd_handlers_to_call_current)
- {
- fd_handlers_to_call_current = fd_handlers_to_call;
- fd_handlers_to_call = NULL;
- }
+ // grab a new list
+ if (!pd->fd_handlers_to_call_current)
+ {
+ pd->fd_handlers_to_call_current = pd->fd_handlers_to_call;
+ pd->fd_handlers_to_call = NULL;
+ }
- if (!fd_handlers_to_call_current) return;
+ if (!pd->fd_handlers_to_call_current) return;
eina_evlog("+fd_handlers", NULL, 0.0, NULL);
- while (fd_handlers_to_call_current)
- {
- Ecore_Fd_Handler *fdh = fd_handlers_to_call_current;
-
- if (!fdh->delete_me)
- {
- if ((fdh->read_active) ||
- (fdh->write_active) ||
- (fdh->error_active))
- {
- fdh->references++;
- if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh))
- {
- if (!fdh->delete_me)
- {
- fdh->delete_me = EINA_TRUE;
- _ecore_main_fdh_poll_del(fdh);
- fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
- }
- }
- fdh->references--;
+ while (pd->fd_handlers_to_call_current)
+ {
+ Ecore_Fd_Handler *fdh = pd->fd_handlers_to_call_current;
+
+ if (!fdh->delete_me)
+ {
+ if ((fdh->read_active) ||
+ (fdh->write_active) ||
+ (fdh->error_active))
+ {
+ fdh->references++;
+ if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh))
+ {
+ if (!fdh->delete_me)
+ {
+ fdh->delete_me = EINA_TRUE;
+ _ecore_main_fdh_poll_del(pd, fdh);
+ pd->fd_handlers_to_delete = eina_list_append
+ (pd->fd_handlers_to_delete, fdh);
+ }
+ }
+ fdh->references--;
#ifdef EFL_EXTRA_SANITY_CHECKS
- _ecore_fd_valid();
+ _ecore_fd_valid(obj, pd);
#endif
+ fdh->read_active = EINA_FALSE;
+ fdh->write_active = EINA_FALSE;
+ fdh->error_active = EINA_FALSE;
+ }
+ }
- fdh->read_active = EINA_FALSE;
- fdh->write_active = EINA_FALSE;
- fdh->error_active = EINA_FALSE;
- }
- }
-
- /* stop when we point to ourselves */
- if (fdh->next_ready == fdh)
- {
- fdh->next_ready = NULL;
- fd_handlers_to_call_current = NULL;
- break;
- }
+ // stop when we point to ourselves
+ if (fdh->next_ready == fdh)
+ {
+ fdh->next_ready = NULL;
+ pd->fd_handlers_to_call_current = NULL;
+ break;
+ }
- fd_handlers_to_call_current = fdh->next_ready;
- fdh->next_ready = NULL;
+ pd->fd_handlers_to_call_current = fdh->next_ready;
+ fdh->next_ready = NULL;
}
eina_evlog("-fd_handlers", NULL, 0.0, NULL);
}
static int
-_ecore_main_fd_handlers_buf_call(void)
+_ecore_main_fd_handlers_buf_call(Eo *obj, Efl_Loop_Data *pd)
{
Ecore_Fd_Handler *fdh;
Eina_List *l, *l2;
int ret;
- if (!fd_handlers_with_buffer) return 0;
+ if (!pd->fd_handlers_with_buffer) return 0;
eina_evlog("+fd_handlers_buf", NULL, 0.0, NULL);
ret = 0;
- EINA_LIST_FOREACH_SAFE(fd_handlers_with_buffer, l, l2, fdh)
+ EINA_LIST_FOREACH_SAFE(pd->fd_handlers_with_buffer, l, l2, fdh)
{
if (!fdh)
{
- fd_handlers_with_buffer = eina_list_remove_list(l, fd_handlers_with_buffer);
+ pd->fd_handlers_with_buffer = eina_list_remove_list
+ (l, pd->fd_handlers_with_buffer);
continue;
}
if ((!fdh->delete_me) && fdh->buf_func)
@@ -2100,12 +2071,13 @@ _ecore_main_fd_handlers_buf_call(void)
{
ret |= _ecore_call_fd_cb(fdh->func, fdh->data, fdh);
fdh->read_active = EINA_TRUE;
- _ecore_try_add_to_call_list(fdh);
+ _ecore_try_add_to_call_list(obj, pd, fdh);
}
fdh->references--;
}
else
- fd_handlers_with_buffer = eina_list_remove_list(fd_handlers_with_buffer, l);
+ pd->fd_handlers_with_buffer = eina_list_remove_list
+ (pd->fd_handlers_with_buffer, l);
}
eina_evlog("-fd_handlers_buf", NULL, 0.0, NULL);
return ret;
@@ -2113,111 +2085,107 @@ _ecore_main_fd_handlers_buf_call(void)
#ifdef HAVE_LIBUV
static void
-_ecore_main_loop_uv_prepare(uv_prepare_t* handle EINA_UNUSED)
+_ecore_main_loop_uv_prepare(uv_prepare_t *handle EINA_UNUSED)
{
+ Eo *obj = ML_OBJ;
+ Efl_Loop_Data *pd = ML_DAT;
+ double t = -1;
+
_dl_uv_timer_stop(&_ecore_main_uv_handle_timers);
- if(in_main_loop == 0 && do_quit)
- {
- _ecore_main_fd_handlers_cleanup();
-
- while (fd_handlers)
- {
- Ecore_Fd_Handler *fdh;
-
- fdh = fd_handlers;
- fd_handlers = (Ecore_Fd_Handler *)eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
- EINA_INLIST_GET(fdh));
- fdh->delete_me = 1;
- _ecore_main_fdh_poll_del(fdh);
- ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
- ecore_fd_handler_mp_free(fdh);
- }
- if (fd_handlers_with_buffer)
- fd_handlers_with_buffer = eina_list_free(fd_handlers_with_buffer);
- if (fd_handlers_with_prep)
- fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep);
- if (fd_handlers_to_delete)
- fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete);
- if (file_fd_handlers)
- file_fd_handlers = eina_list_free(file_fd_handlers);
-
- fd_handlers_to_call = NULL;
- fd_handlers_to_call_current = NULL;
- fd_handlers_to_delete = NULL;
- fd_handler_current = NULL;
-
- _dl_uv_prepare_stop(&_ecore_main_uv_prepare);
- _dl_uv_check_stop(&_ecore_main_uv_check);
- _dl_uv_stop(_dl_uv_default_loop());
-
- return;
+ if ((pd->in_loop == 0) && (pd->do_quit))
+ {
+ _ecore_main_fd_handlers_cleanup(obj, pd);
+
+ while (pd->fd_handlers)
+ {
+ Ecore_Fd_Handler *fdh = pd->fd_handlers;
+ pd->fd_handlers = (Ecore_Fd_Handler *)
+ eina_inlist_remove(EINA_INLIST_GET(pd->fd_handlers),
+ EINA_INLIST_GET(fdh));
+ fdh->delete_me = 1;
+ _ecore_main_fdh_poll_del(pd, fdh);
+ ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
+ ecore_fd_handler_mp_free(fdh);
+ }
+ if (pd->fd_handlers_with_buffer)
+ pd->fd_handlers_with_buffer = eina_list_free(pd->fd_handlers_with_buffer);
+ if (pd->fd_handlers_with_prep)
+ pd->fd_handlers_with_prep = eina_list_free(pd->fd_handlers_with_prep);
+ if (pd->fd_handlers_to_delete)
+ pd->fd_handlers_to_delete = eina_list_free(pd->fd_handlers_to_delete);
+ if (pd->file_fd_handlers)
+ pd->file_fd_handlers = eina_list_free(pd->file_fd_handlers);
+
+ pd->fd_handlers_to_call = NULL;
+ pd->fd_handlers_to_call_current = NULL;
+
+ _dl_uv_prepare_stop(&_ecore_main_uv_prepare);
+ _dl_uv_check_stop(&_ecore_main_uv_check);
+ _dl_uv_stop(_dl_uv_default_loop());
+
+ return;
}
in_main_loop++;
+ pd->in_loop = in_main_loop;
- if(!_ecore_main_uv_idling)
+ if (!_ecore_main_uv_idling)
{
_ecore_main_uv_idling = EINA_TRUE;
- _ecore_idle_enterer_call(_mainloop_singleton);
+ _ecore_idle_enterer_call(obj);
_ecore_throttle();
+ _throttle_do(pd);
}
- double t = -1;
- if(_ecore_main_uv_idling)
+ if (_ecore_main_uv_idling)
{
- _ecore_idler_all_call(_mainloop_singleton);
- DBG("called idles");
- if(_ecore_idler_exist(_mainloop_singleton) || _ecore_event_exist())
- t = 0.0;
+ _ecore_idler_all_call(obj);
+ DBG("called idles");
+ if (_ecore_idler_exist(_obj) || efl_loop_message_exists(obj)) t = 0.0;
}
- if (do_quit)
+ if (pd->do_quit)
{
- DBG("do quit outside loop");
-
- if(_ecore_main_uv_idling)
- {
- _ecore_idle_exiter_call(_mainloop_singleton);
- _ecore_animator_run_reset();
-
- _ecore_main_uv_idling = EINA_FALSE;
- }
+ DBG("do quit outside loop");
- t = -1;
-
- _ecore_time_loop_time = ecore_time_get();
- _efl_loop_timer_enable_new();
-
- goto done;
+ if (_ecore_main_uv_idling)
+ {
+ _ecore_idle_exiter_call(obj);
+ _ecore_animator_run_reset();
+ _ecore_main_uv_idling = EINA_FALSE;
+ }
+ t = -1;
+ pd->loop_time = ecore_time_get();
+ _efl_loop_timer_enable_new(obj, pd);
+ goto done;
}
- assert(!fd_handlers_to_call);
+ assert(!pd->fd_handlers_to_call);
- _ecore_time_loop_time = ecore_time_get();
- _efl_loop_timer_enable_new();
- if (_efl_loop_timers_exists() || t >= 0)
+ pd->loop_time = ecore_time_get();
+ _efl_loop_timer_enable_new(obj, pd);
+ if (_efl_loop_timers_exists(obj, pd) || (t >= 0))
{
- double tnext = _efl_loop_timer_next_get();
- if (t < 0 || (tnext >= 0 && tnext < t)) t = tnext;
- DBG("Should awake after %f", t);
-
- if (t >= 0.0)
- {
- //_dl_uv_timer_stop(&_ecore_main_uv_handle_timers);
- _dl_uv_timer_start(&_ecore_main_uv_handle_timers, &_ecore_main_loop_timer_run, t * 1000
- , 0);
- }
- else
- DBG("Is not going to awake with timer");
- }
- else
- DBG("Is not going to awake with timer");
+ double tnext = _efl_loop_timer_next_get(obj, pd);
+
+ if ((t < 0) || ((tnext >= 0) && (tnext < t))) t = tnext;
+ DBG("Should awake after %f", t);
- done:
- if (fd_handlers_with_prep)
- _ecore_main_prepare_handlers();
+ if (t >= 0.0)
+ {
+ // _dl_uv_timer_stop(&_ecore_main_uv_handle_timers);
+ _dl_uv_timer_start(&_ecore_main_uv_handle_timers,
+ &_ecore_main_loop_timer_run,
+ t * 1000, 0);
+ }
+ else DBG("Is not going to awake with timer");
+ }
+ else DBG("Is not going to awake with timer");
+done:
+ if (pd->fd_handlers_with_prep) _ecore_main_prepare_handlers(obj, pd);
in_main_loop--;
+ pd->in_loop = in_main_loop;
}
#endif
@@ -2229,56 +2197,57 @@ enum {
};
static int
-_ecore_main_loop_spin_core(void)
-{
- /* as we are spinning we need to update loop time per spin */
- _ecore_time_loop_time = ecore_time_get();
- /* call all idlers */
- _ecore_idler_all_call(_mainloop_singleton);
- /* which returns false if no more idelrs exist */
- if (!_ecore_idler_exist(_mainloop_singleton)) return SPIN_RESTART;
- /* sneaky - drop through or if checks - the first one to succeed
- * drops through and returns "continue" so further ones dont run */
- if ((_ecore_main_select(0.0) > 0) || (_ecore_event_exist()) ||
- (_ecore_signal_count_get() > 0) || (do_quit))
- return LOOP_CONTINUE;
- /* default - spin more */
- return SPIN_MORE;
+_ecore_main_loop_spin_core(Eo *obj, Efl_Loop_Data *pd)
+{
+ // as we are spinning we need to update loop time per spin
+ pd->loop_time = ecore_time_get();
+ // call all idlers
+ _ecore_idler_all_call(obj);
+ // which returns false if no more idelrs exist
+ if (!_ecore_idler_exist(obj)) return SPIN_RESTART;
+ // sneaky - drop through or if checks - the first one to succeed
+ // drops through and returns "continue" so further ones dont run
+ if ((_ecore_main_select(obj, pd, 0.0) > 0) ||
+ (efl_loop_message_exists(obj)) ||
+ (_ecore_signal_count_get(obj, pd) > 0) || (pd->do_quit))
+ return LOOP_CONTINUE;
+ // default - spin more
+ return SPIN_MORE;
}
static int
-_ecore_main_loop_spin_no_timers(void)
-{
- /* if we have idlers we HAVE to spin and handle everything
- * in a polling way - spin in a tight polling loop */
- for (;; )
- {
- int action = _ecore_main_loop_spin_core();
- if (action != SPIN_MORE) return action;
- /* if an idler has added a timer then we need to go through
- * the start of the spin cycle again to handle cases properly */
- if (_efl_loop_timers_exists()) return SPIN_RESTART;
- }
- /* just contiune handling events etc. */
- return LOOP_CONTINUE;
+_ecore_main_loop_spin_no_timers(Eo *obj, Efl_Loop_Data *pd)
+{
+ // if we have idlers we HAVE to spin and handle everything
+ // in a polling way - spin in a tight polling loop
+ for (;;)
+ {
+ int action = _ecore_main_loop_spin_core(obj, pd);
+ if (action != SPIN_MORE) return action;
+ // if an idler has added a timer then we need to go through
+ // the start of the spin cycle again to handle cases properly
+ if (_efl_loop_timers_exists(obj, pd)) return SPIN_RESTART;
+ }
+ // just contiune handling events etc.
+ return LOOP_CONTINUE;
}
static int
-_ecore_main_loop_spin_timers(void)
-{
- /* if we have idlers we HAVE to spin and handle everything
- * in a polling way - spin in a tight polling loop */
- for (;; )
- {
- int action = _ecore_main_loop_spin_core();
- if (action != SPIN_MORE) return action;
- /* if next timer expires now or in the past - stop spinning and
- * continue the mainloop walk as our "select" timeout has
- * expired now */
- if (_efl_loop_timer_next_get() <= 0.0) return LOOP_CONTINUE;
- }
- /* just contiune handling events etc. */
- return LOOP_CONTINUE;
+_ecore_main_loop_spin_timers(Eo *obj, Efl_Loop_Data *pd)
+{
+ // if we have idlers we HAVE to spin and handle everything
+ // in a polling way - spin in a tight polling loop
+ for (;;)
+ {
+ int action = _ecore_main_loop_spin_core(obj, pd);
+ if (action != SPIN_MORE) return action;
+ // if next timer expires now or in the past - stop spinning and
+ // continue the mainloop walk as our "select" timeout has
+ // expired now
+ if (_efl_loop_timer_next_get(obj, pd) <= 0.0) return LOOP_CONTINUE;
+ }
+ // just contiune handling events etc.
+ return LOOP_CONTINUE;
}
static void
@@ -2297,163 +2266,168 @@ _ecore_fps_marker_2(void)
}
static void
-_ecore_main_loop_iterate_internal(int once_only)
+_ecore_main_loop_iterate_internal(Eo *obj, Efl_Loop_Data *pd, int once_only)
{
double next_time = -1.0;
Eo *f, *p;
- in_main_loop++;
-
- /* destroy all optional futures */
- EINA_LIST_FREE(_pending_futures, f)
- efl_del(f);
-
- /* and propagate all promise value */
- EINA_LIST_FREE(_pending_promises, p)
- ecore_loop_promise_fulfill(p);
-
- /* expire any timers */
- _efl_loop_timer_expired_timers_call(_ecore_time_loop_time);
-
- /* process signals into events .... */
- _ecore_signal_received_process();
- /* if as a result of timers/animators or signals we have accumulated
- * events, then instantly handle them */
- if (_ecore_event_exist())
- {
- /* but first conceptually enter an idle state */
- _ecore_idle_enterer_call(_mainloop_singleton);
+ if (obj == ML_OBJ)
+ {
+ in_main_loop++;
+ pd->in_loop = in_main_loop;
+ }
+ // destroy all optional futures
+ EINA_LIST_FREE(pd->pending_futures, f) efl_del(f);
+ // and propagate all promise value
+ Eina_List *tmp = pd->pending_promises;
+ pd->pending_promises = NULL;
+ EINA_LIST_FREE(tmp, p) ecore_loop_promise_fulfill(p);
+ // expire any timers
+ _efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time);
+ // process signals into events ....
+ if (obj == ML_OBJ) _ecore_signal_received_process(obj, pd);
+ // if as a result of timers/animators or signals we have accumulated
+ // events, then instantly handle them
+ if (efl_loop_message_exists(obj))
+ {
+ // but first conceptually enter an idle state
+ _ecore_idle_enterer_call(obj);
_ecore_throttle();
- /* now quickly poll to see which input fd's are active */
- _ecore_main_select(0.0);
- /* allow newly queued timers to expire from now on */
- _efl_loop_timer_enable_new();
- /* go straight to processing the events we had queued */
+ _throttle_do(pd);
+ // now quickly poll to see which input fd's are active
+ _ecore_main_select(obj, pd, 0.0);
+ // allow newly queued timers to expire from now on
+ _efl_loop_timer_enable_new(obj, pd);
+ // go straight to processing the events we had queued
goto process_all;
}
if (once_only)
{
- /* in once_only mode we should quickly poll for inputs, signals
- * if we got any events or signals, allow new timers to process.
- * use bitwise or to force both conditions to be tested and
- * merged together */
- if (_ecore_main_select(0.0) | _ecore_signal_count_get())
+ // in once_only mode we should quickly poll for inputs, signals
+ // if we got any events or signals, allow new timers to process.
+ // use bitwise or to force both conditions to be tested and
+ // merged together
+ if (_ecore_main_select(obj, pd, 0.0) |
+ _ecore_signal_count_get(obj, pd))
{
- _efl_loop_timer_enable_new();
+ _efl_loop_timer_enable_new(obj, pd);
goto process_all;
}
}
else
{
- /* call idle enterers ... */
- _ecore_idle_enterer_call(_mainloop_singleton);
+ // call idle enterers ...
+ _ecore_idle_enterer_call(obj);
_ecore_throttle();
+ _throttle_do(pd);
}
- /* if these calls caused any buffered events to appear - deal with them */
- if (fd_handlers_with_buffer)
- _ecore_main_fd_handlers_buf_call();
+ // if these calls caused any buffered events to appear - deal with them
+ if (pd->fd_handlers_with_buffer)
+ _ecore_main_fd_handlers_buf_call(obj, pd);
- /* if there are any (buffered fd handling may generate them)
- * then jump to processing them */
- if (_ecore_event_exist())
+ // if there are any (buffered fd handling may generate them)
+ // then jump to processing them */
+ if (efl_loop_message_exists(obj))
{
- _ecore_main_select(0.0);
- _efl_loop_timer_enable_new();
+ _ecore_main_select(obj, pd, 0.0);
+ _efl_loop_timer_enable_new(obj, pd);
goto process_all;
}
if (once_only)
{
- /* in once_only mode enter idle here instead and then return */
- _ecore_idle_enterer_call(_mainloop_singleton);
+ // in once_only mode enter idle here instead and then return
+ _ecore_idle_enterer_call(obj);
_ecore_throttle();
- _efl_loop_timer_enable_new();
+ _throttle_do(pd);
+ _efl_loop_timer_enable_new(obj, pd);
goto done;
}
- _ecore_fps_marker_1();
-
- /* start of the sleeping or looping section */
-start_loop: /*-*************************************************************/
- /* We could be looping here without exiting the function and we need to
- process future and promise before the next waiting period. */
- /* destroy all optional futures */
- EINA_LIST_FREE(_pending_futures, f)
- efl_del(f);
-
- /* and propagate all promise value */
- EINA_LIST_FREE(_pending_promises, p)
- ecore_loop_promise_fulfill(p);
-
- /* any timers re-added as a result of these are allowed to go */
- _efl_loop_timer_enable_new();
- /* if we have been asked to quit the mainloop then exit at this point */
- if (do_quit)
- {
- _efl_loop_timer_enable_new();
+ if (obj == ML_OBJ) _ecore_fps_marker_1();
+
+ // start of the sleeping or looping section
+start_loop: //-*************************************************************
+ // We could be looping here without exiting the function and we need to
+ // process future and promise before the next waiting period.
+ // destroy all optional futures
+ EINA_LIST_FREE(pd->pending_futures, f) efl_del(f);
+ // and propagate all promise value
+ tmp = pd->pending_promises;
+ pd->pending_promises = NULL;
+ EINA_LIST_FREE(tmp, p) ecore_loop_promise_fulfill(p);
+ // any timers re-added as a result of these are allowed to go
+ _efl_loop_timer_enable_new(obj, pd);
+ // if we have been asked to quit the mainloop then exit at this point
+ if (pd->do_quit)
+ {
+ _efl_loop_timer_enable_new(obj, pd);
goto done;
}
- if (!_ecore_event_exist())
+ if (!efl_loop_message_exists(obj))
{
- /* init flags */
- next_time = _efl_loop_timer_next_get();
- /* no idlers */
- if (!_ecore_idler_exist(_mainloop_singleton))
+ // init flags
+ next_time = _efl_loop_timer_next_get(obj, pd);
+ // no idlers
+ if (!_ecore_idler_exist(obj))
{
- /* sleep until timeout or forever (-1.0) waiting for on fds */
- _ecore_main_select(next_time);
+ // sleep until timeout or forever (-1.0) waiting for on fds
+ _ecore_main_select(obj, pd, next_time);
}
else
{
int action = LOOP_CONTINUE;
- /* no timers - spin */
- if (next_time < 0) action = _ecore_main_loop_spin_no_timers();
+ // no timers - spin
+ if (next_time < 0) action = _ecore_main_loop_spin_no_timers(obj, pd);
/* timers - spin */
- else action = _ecore_main_loop_spin_timers();
+ else action = _ecore_main_loop_spin_timers(obj, pd);
if (action == SPIN_RESTART) goto start_loop;
}
}
- _ecore_fps_marker_2();
+ if (obj == ML_OBJ) _ecore_fps_marker_2();
- /* actually wake up and deal with input, events etc. */
-process_all: /*-*********************************************************/
+ // actually wake up and deal with input, events etc.
+process_all: //-*********************************************************
- /* we came out of our "wait state" so idle has exited */
+ // we came out of our "wait state" so idle has exited
if (!once_only)
{
- _ecore_animator_run_reset();
- _ecore_idle_exiter_call(_mainloop_singleton);
- }
- /* call the fd handler per fd that became alive... */
- /* this should read or write any data to the monitored fd and then */
- /* post events onto the ecore event pipe if necessary */
- _ecore_main_fd_handlers_call();
- if (fd_handlers_with_buffer) _ecore_main_fd_handlers_buf_call();
- /* process signals into events .... */
- _ecore_signal_received_process();
- /* handle events ... */
- _ecore_event_call();
- _ecore_main_fd_handlers_cleanup();
+ _ecore_animator_run_reset(); // XXX:
+ _ecore_idle_exiter_call(obj);
+ }
+ // call the fd handler per fd that became alive...
+ // this should read or write any data to the monitored fd and then
+ // post events onto the ecore event pipe if necessary
+ _ecore_main_fd_handlers_call(obj, pd);
+ if (pd->fd_handlers_with_buffer) _ecore_main_fd_handlers_buf_call(obj, pd);
+ // process signals into events ....
+ _ecore_signal_received_process(obj, pd);
+ // handle events ...
+ efl_loop_message_process(obj); // XXX: event queue per loop
+ _ecore_main_fd_handlers_cleanup(obj, pd);
if (once_only)
{
- /* if in once_only mode handle idle exiting */
- _ecore_idle_enterer_call(_mainloop_singleton);
+ // if in once_only mode handle idle exiting
+ _ecore_idle_enterer_call(obj);
_ecore_throttle();
+ _throttle_do(pd);
}
-done: /*-*****************************************************************/
- /* Agressively flush animator */
+done: //-*****************************************************************
+ // Agressively flush animator
_ecore_animator_flush();
if (!once_only)
+ eina_slstr_local_clear(); // Free all short lived strings
+
+ if (obj == ML_OBJ)
{
- /* Free all short lived strings */
- eina_slstr_local_clear();
+ in_main_loop--;
+ pd->in_loop = in_main_loop;
}
- in_main_loop--;
}
#endif
@@ -2461,24 +2435,20 @@ done: /*-*****************************************************************/
#ifdef _WIN32
typedef struct
{
- DWORD objects_nbr;
+ DWORD objects_nbr;
HANDLE *objects;
- DWORD timeout;
+ DWORD timeout;
} Ecore_Main_Win32_Thread_Data;
static unsigned int __stdcall
_ecore_main_win32_objects_wait_thread(void *data)
{
- Ecore_Main_Win32_Thread_Data *td;
- DWORD result;
-
- td = (Ecore_Main_Win32_Thread_Data *)data;
- result = MsgWaitForMultipleObjects(td->objects_nbr,
- (const HANDLE *)td->objects,
- FALSE,
- td->timeout,
- QS_ALLINPUT);
- return result;
+ Ecore_Main_Win32_Thread_Data *td = (Ecore_Main_Win32_Thread_Data *)data;
+ return MsgWaitForMultipleObjects(td->objects_nbr,
+ (const HANDLE *)td->objects,
+ FALSE,
+ td->timeout,
+ QS_ALLINPUT);
}
static DWORD
@@ -2488,26 +2458,19 @@ _ecore_main_win32_objects_wait(DWORD objects_nbr,
{
Ecore_Main_Win32_Thread_Data *threads_data;
HANDLE *threads_handles;
- DWORD threads_nbr;
- DWORD threads_remain;
- DWORD objects_idx;
- DWORD result;
- DWORD i;
+ DWORD threads_nbr threads_remain, objects_idx, result, i;
if (objects_nbr < MAXIMUM_WAIT_OBJECTS)
return MsgWaitForMultipleObjects(objects_nbr,
objects,
EINA_FALSE,
timeout, QS_ALLINPUT);
- /*
- * too much objects, so we launch a bunch of threads to
- * wait for, each one calls MsgWaitForMultipleObjects
- */
+ // too much objects, so we launch a bunch of threads to
+ // wait for, each one calls MsgWaitForMultipleObjects
threads_nbr = objects_nbr / (MAXIMUM_WAIT_OBJECTS - 1);
threads_remain = objects_nbr % (MAXIMUM_WAIT_OBJECTS - 1);
- if (threads_remain > 0)
- threads_nbr++;
+ if (threads_remain > 0) threads_nbr++;
if (threads_nbr > MAXIMUM_WAIT_OBJECTS)
{
@@ -2522,7 +2485,8 @@ _ecore_main_win32_objects_wait(DWORD objects_nbr,
return WAIT_FAILED;
}
- threads_data = (Ecore_Main_Win32_Thread_Data *)malloc(threads_nbr * sizeof(Ecore_Main_Win32_Thread_Data));
+ threads_data = (Ecore_Main_Win32_Thread_Data *)
+ malloc(threads_nbr * sizeof(Ecore_Main_Win32_Thread_Data));
if (!threads_data)
{
ERR("Can not allocate memory for the waiting thread.");
@@ -2546,12 +2510,9 @@ _ecore_main_win32_objects_wait(DWORD objects_nbr,
objects_idx += (MAXIMUM_WAIT_OBJECTS - 1);
}
- threads_handles[i] = (HANDLE)_beginthreadex(NULL,
- 0,
- _ecore_main_win32_objects_wait_thread,
- &threads_data[i],
- 0,
- NULL);
+ threads_handles[i] = (HANDLE)_beginthreadex
+ (NULL, 0, _ecore_main_win32_objects_wait_thread,
+ &threads_data[i], 0, NULL);
if (!threads_handles[i])
{
DWORD j;
@@ -2567,22 +2528,21 @@ _ecore_main_win32_objects_wait(DWORD objects_nbr,
result = WaitForMultipleObjects(threads_nbr,
threads_handles,
- FALSE, /* we wait until one thread is signaled */
+ FALSE, // we wait until one thread signaled
INFINITE);
if (result < (WAIT_OBJECT_0 + threads_nbr))
{
DWORD wait_res;
- /*
- * One of the thread callback has exited so we retrieve
- * its exit status, that is the returned value of
- * MsgWaitForMultipleObjects()
- */
+ // One of the thread callback has exited so we retrieve
+ // its exit status, that is the returned value of
+ // MsgWaitForMultipleObjects()
if (GetExitCodeThread(threads_handles[result - WAIT_OBJECT_0],
&wait_res))
{
- WaitForMultipleObjects(threads_nbr, threads_handles, TRUE, INFINITE);
+ WaitForMultipleObjects(threads_nbr, threads_handles,
+ TRUE, INFINITE);
for (i = 0; i < threads_nbr; i++)
CloseHandle(threads_handles[i]);
free(threads_data);
@@ -2598,13 +2558,12 @@ _ecore_main_win32_objects_wait(DWORD objects_nbr,
goto close_thread;
}
- close_thread:
+close_thread:
WaitForMultipleObjects(threads_nbr, threads_handles, TRUE, INFINITE);
- for (i = 0; i < threads_nbr; i++)
- CloseHandle(threads_handles[i]);
- free_threads_data:
+ for (i = 0; i < threads_nbr; i++) CloseHandle(threads_handles[i]);
+free_threads_data:
free(threads_data);
- free_threads_handles:
+free_threads_handles:
free(threads_handles);
return WAIT_FAILED;
@@ -2615,7 +2574,6 @@ _stdin_wait_thread(void *data EINA_UNUSED)
{
int c = getc(stdin);
ungetc(c, stdin);
-
return 0;
}
@@ -2626,39 +2584,41 @@ _ecore_main_win32_select(int nfds EINA_UNUSED,
fd_set *exceptfds,
struct timeval *tv)
{
+ Eo *obj = ML_OBJ;
+ Efl_Loop_Data *pd = ML_DAT;
HANDLE *objects;
- static HANDLE stdin_wait_thread = INVALID_HANDLE_VALUE;
- Eina_Bool stdin_thread_done = EINA_FALSE;
- HANDLE stdin_handle;
int *sockets;
Ecore_Fd_Handler *fdh;
Ecore_Win32_Handler *wh;
+ static HANDLE stdin_wait_thread = INVALID_HANDLE_VALUE;
+ HANDLE stdin_handle;
+ DWORD result, timeout;
+ MSG msg;
unsigned int fds_nbr = 0;
unsigned int objects_nbr = 0;
unsigned int events_nbr = 0;
- DWORD result;
- DWORD timeout;
- MSG msg;
unsigned int i;
int res;
+ Eina_Bool stdin_thread_done = EINA_FALSE;
- fds_nbr = eina_inlist_count(EINA_INLIST_GET(fd_handlers));
+ fds_nbr = eina_inlist_count(EINA_INLIST_GET(pd->fd_handlers));
sockets = (int *)malloc(fds_nbr * sizeof(int));
- if (!sockets)
- return -1;
+ if (!sockets) return -1;
- objects = (HANDLE)malloc((fds_nbr + eina_inlist_count(EINA_INLIST_GET(win32_handlers))) * sizeof(HANDLE));
+ objects = (HANDLE)malloc((fds_nbr +
+ eina_inlist_count
+ (EINA_INLIST_GET(pd->win32_handlers)))
+ * sizeof(HANDLE));
if (!objects)
{
free(sockets);
return -1;
}
- /* Create an event object per socket */
- EINA_INLIST_FOREACH(fd_handlers, fdh)
+ // Create an event object per socket
+ EINA_INLIST_FOREACH(pd->fd_handlers, fdh)
{
- if (fdh->delete_me)
- continue;
+ if (fdh->delete_me) continue;
WSAEVENT event;
long network_event;
@@ -2691,11 +2651,10 @@ _ecore_main_win32_select(int nfds EINA_UNUSED,
}
}
stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
- /* store the HANDLEs in the objects to wait for */
- EINA_INLIST_FOREACH(win32_handlers, wh)
+ // store the HANDLEs in the objects to wait for
+ EINA_INLIST_FOREACH(pd->win32_handlers, wh)
{
- if (wh->delete_me)
- continue;
+ if (wh->delete_me) continue;
if (wh->h == stdin_handle)
{
@@ -2708,26 +2667,21 @@ _ecore_main_win32_select(int nfds EINA_UNUSED,
NULL);
objects[objects_nbr] = stdin_wait_thread;
}
- else
- {
- objects[objects_nbr] = wh->h;
- }
+ else objects[objects_nbr] = wh->h;
objects_nbr++;
}
- /* Empty the queue before waiting */
+ // Empty the queue before waiting
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
- /* Wait for any message sent or posted to this queue */
- /* or for one of the passed handles be set to signaled. */
- if (!tv)
- timeout = INFINITE;
- else
- timeout = (DWORD)((tv->tv_sec * 1000.0) + (tv->tv_usec / 1000.0));
+ // Wait for any message sent or posted to this queue
+ // or for one of the passed handles be set to signaled.
+ if (!tv) timeout = INFINITE;
+ else timeout = (DWORD)((tv->tv_sec * 1000.0) + (tv->tv_usec / 1000.0));
if (timeout == 0)
{
@@ -2738,15 +2692,10 @@ _ecore_main_win32_select(int nfds EINA_UNUSED,
result = _ecore_main_win32_objects_wait(objects_nbr,
(const HANDLE *)objects,
timeout);
-
- if (readfds)
- FD_ZERO(readfds);
- if (writefds)
- FD_ZERO(writefds);
- if (exceptfds)
- FD_ZERO(exceptfds);
-
- /* The result tells us the type of event we have. */
+ if (readfds) FD_ZERO(readfds);
+ if (writefds) FD_ZERO(writefds);
+ if (exceptfds) FD_ZERO(exceptfds);
+ // The result tells us the type of event we have.
if (result == WAIT_FAILED)
{
WRN("%s", evil_last_error_get());
@@ -2764,7 +2713,6 @@ _ecore_main_win32_select(int nfds EINA_UNUSED,
TranslateMessage(&msg);
DispatchMessage(&msg);
}
-
res = 0;
}
else if (result < WAIT_OBJECT_0 + events_nbr)
@@ -2772,39 +2720,37 @@ _ecore_main_win32_select(int nfds EINA_UNUSED,
WSANETWORKEVENTS network_event;
WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
-
- if ((network_event.lNetworkEvents & (FD_READ | FD_CONNECT | FD_ACCEPT)) && readfds)
+ if ((network_event.lNetworkEvents &
+ (FD_READ | FD_CONNECT | FD_ACCEPT)) && readfds)
FD_SET(sockets[result], readfds);
- if ((network_event.lNetworkEvents & (FD_WRITE | FD_CLOSE)) && writefds)
+ if ((network_event.lNetworkEvents &
+ (FD_WRITE | FD_CLOSE)) && writefds)
FD_SET(sockets[result], writefds);
if ((network_event.lNetworkEvents & FD_OOB) && exceptfds)
FD_SET(sockets[result], exceptfds);
-
res = 1;
}
else if ((result >= (WAIT_OBJECT_0 + events_nbr)) &&
(result < (WAIT_OBJECT_0 + objects_nbr)))
{
- if (!win32_handler_current)
- {
- /* regular main loop, start from head */
- win32_handler_current = win32_handlers;
- }
+ if (!pd->win32_handler_current)
+ // regular main loop, start from head
+ pd->win32_handler_current = pd->win32_handlers;
else
- {
- /* recursive main loop, continue from where we were */
- win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
- }
+ // recursive main loop, continue from where we were
+ pd->win32_handler_current = (Ecore_Win32_Handler *)
+ EINA_INLIST_GET(pd->win32_handler_current)->next;
if (objects[result - WAIT_OBJECT_0] == stdin_wait_thread)
stdin_thread_done = EINA_TRUE;
- while (win32_handler_current)
+ while (pd->win32_handler_current)
{
- wh = win32_handler_current;
+ wh = pd->win32_handler_current;
- if (objects[result - WAIT_OBJECT_0] == wh->h ||
- (objects[result - WAIT_OBJECT_0] == stdin_wait_thread && wh->h == stdin_handle))
+ if ((objects[result - WAIT_OBJECT_0] == wh->h) ||
+ ((objects[result - WAIT_OBJECT_0] == stdin_wait_thread) &&
+ (wh->h == stdin_handle)))
{
if (!wh->delete_me)
{
@@ -2812,13 +2758,16 @@ _ecore_main_win32_select(int nfds EINA_UNUSED,
if (!wh->func(wh->data, wh))
{
wh->delete_me = EINA_TRUE;
- win32_handlers_to_delete = eina_list_append(win32_handlers_to_delete, wh);
+ pd->win32_handlers_to_delete = eina_list_append
+ (pd->win32_handlers_to_delete, wh);
}
wh->references--;
}
}
- if (win32_handler_current) /* may have changed in recursive main loops */
- win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
+ if (pd->win32_handler_current)
+ // may have changed in recursive main loops
+ pd->win32_handler_current = (Ecore_Win32_Handler *)
+ EINA_INLIST_GET(pd->win32_handler_current)->next;
}
res = 1;
}
@@ -2828,508 +2777,14 @@ _ecore_main_win32_select(int nfds EINA_UNUSED,
res = -1;
}
-err :
- /* Remove event objects again */
+err:
+ // Remove event objects again
for (i = 0; i < events_nbr; i++) WSACloseEvent(objects[i]);
- if (stdin_thread_done)
- stdin_wait_thread = INVALID_HANDLE_VALUE;
+ if (stdin_thread_done) stdin_wait_thread = INVALID_HANDLE_VALUE;
free(objects);
free(sockets);
return res;
}
-
#endif
-
-Eo *_mainloop_singleton = NULL;
-
-EOLIAN static Efl_Loop *
-_efl_loop_main_get(Efl_Class *klass EINA_UNUSED, void *_pd EINA_UNUSED)
-{
- if (!_mainloop_singleton)
- {
- _mainloop_singleton = efl_add(EFL_LOOP_CLASS, NULL);
- }
-
- return _mainloop_singleton;
-}
-
-EAPI Eo *
-ecore_main_loop_get(void)
-{
- return efl_loop_main_get(EFL_LOOP_CLASS);
-}
-
-EOLIAN static void
-_efl_loop_iterate(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
-{
- ecore_main_loop_iterate();
-}
-
-EOLIAN static int _efl_loop_iterate_may_block(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED, int may_block)
-{
- return ecore_main_loop_iterate_may_block(may_block);
-}
-
-// FIXME: This should return an Eina_Value, but that doesn't work at the moment
-EOLIAN static Eina_Value *
-_efl_loop_begin(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
-{
- ecore_main_loop_begin();
- return &_ecore_exit_code;
-}
-
-EOLIAN static void
-_efl_loop_quit(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED, Eina_Value exit_code)
-{
- ecore_main_loop_quit();
- _ecore_exit_code = exit_code;
-}
-
-EAPI void
-efl_exit(int exit_code)
-{
- Eina_Value v = EINA_VALUE_EMPTY;
-
- eina_value_setup(&v, EINA_VALUE_TYPE_INT);
- eina_value_set(&v, &exit_code);
- efl_loop_quit(ecore_main_loop_get(), v);
-}
-
-EOLIAN static Efl_Object *
-_efl_loop_efl_object_provider_find(Eo *obj, Efl_Loop_Data *pd, const Efl_Object *klass)
-{
- Efl_Object *r;
-
- if (klass == EFL_LOOP_CLASS) return obj;
-
- r = eina_hash_find(pd->providers, &klass);
- if (r) return r;
-
- return efl_provider_find(efl_super(obj, EFL_LOOP_CLASS), klass);
-}
-
-EAPI int
-efl_loop_exit_code_process(Eina_Value *value)
-{
- const Eina_Value_Type *t = eina_value_type_get(value);
- int r = 0;
-
- if (t == EINA_VALUE_TYPE_UCHAR ||
- t == EINA_VALUE_TYPE_USHORT ||
- t == EINA_VALUE_TYPE_UINT ||
- t == EINA_VALUE_TYPE_ULONG ||
- t == EINA_VALUE_TYPE_UINT64 ||
- t == EINA_VALUE_TYPE_CHAR ||
- t == EINA_VALUE_TYPE_SHORT ||
- t == EINA_VALUE_TYPE_INT ||
- t == EINA_VALUE_TYPE_LONG ||
- t == EINA_VALUE_TYPE_INT64 ||
- t == EINA_VALUE_TYPE_FLOAT ||
- t == EINA_VALUE_TYPE_DOUBLE)
- {
- Eina_Value v = EINA_VALUE_EMPTY;
-
- eina_value_setup(&v, EINA_VALUE_TYPE_INT);
- if (!eina_value_convert(&v, value))
- r = -1;
- else
- eina_value_get(&v, &v);
- }
- else
- {
- FILE *out = stdout;
- char *msg;
-
- msg = eina_value_to_string(value);
-
- if (t == EINA_VALUE_TYPE_ERROR)
- {
- r = -1;
- out = stderr;
- }
-
- fprintf(out, "%s\n", msg);
- }
-
- return r;
-}
-
-static void
-_poll_trigger(void *data, const Efl_Event *event)
-{
- Eo *parent = efl_parent_get(event->object);
-
- efl_event_callback_call(parent, data, NULL);
-}
-
-static void
-_check_event_catcher_add(void *data, const Efl_Event *event)
-{
- const Efl_Callback_Array_Item *array = event->info;
- Efl_Loop_Data *pd = data;
- int i;
-
- for (i = 0; array[i].desc != NULL; i++)
- {
- if (array[i].desc == EFL_LOOP_EVENT_IDLE)
- {
- ++pd->idlers;
- }
- // XXX: all the below are kind of bad. ecore_pollers were special.
- // they all woke up at the SAME time based on interval, (all pollers
- // of interval 1 woke up together, those with 2 woke up when 1 and
- // 2 woke up, 4 woke up together along with 1 and 2 etc.
- // the below means they will just go off whenever but at a pre
- // defined interval - 1/60th, 6 and 66 seconds. not really great
- // pollers probably should be less frequent that 1/60th even on poll
- // high, medium probably down to 1-2 sec and low - yes maybe 30 or 60
- // sec... still - not timed to wake up together. :(
- else if (array[i].desc == EFL_LOOP_EVENT_POLL_HIGH)
- {
- if (!pd->poll_high)
- {
- // Would be better to have it in sync with normal wake up
- // of the main loop for better energy efficiency, I guess.
- pd->poll_high = efl_add(EFL_LOOP_TIMER_CLASS, event->object,
- efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_HIGH),
- efl_loop_timer_interval_set(efl_added, 1.0/60.0));
- }
- ++pd->pollers.high;
- }
- else if (array[i].desc == EFL_LOOP_EVENT_POLL_MEDIUM)
- {
- if (!pd->poll_medium)
- {
- pd->poll_medium = efl_add(EFL_LOOP_TIMER_CLASS, event->object,
- efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_MEDIUM),
- efl_loop_timer_interval_set(efl_added, 6));
- }
- ++pd->pollers.medium;
- }
- else if (array[i].desc == EFL_LOOP_EVENT_POLL_LOW)
- {
- if (!pd->poll_low)
- {
- pd->poll_low = efl_add(EFL_LOOP_TIMER_CLASS, event->object,
- efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_LOW),
- efl_loop_timer_interval_set(efl_added, 66));
- }
- ++pd->pollers.low;
- }
- }
-}
-
-static void
-_check_event_catcher_del(void *data, const Efl_Event *event)
-{
- const Efl_Callback_Array_Item *array = event->info;
- Efl_Loop_Data *pd = data;
- int i;
-
- for (i = 0; array[i].desc != NULL; i++)
- {
- if (array[i].desc == EFL_LOOP_EVENT_IDLE)
- {
- --pd->idlers;
- }
- else if (array[i].desc == EFL_LOOP_EVENT_POLL_HIGH)
- {
- --pd->pollers.high;
- if (!pd->pollers.high)
- {
- efl_del(pd->poll_high);
- pd->poll_high = NULL;
- }
- }
- else if (array[i].desc == EFL_LOOP_EVENT_POLL_MEDIUM)
- {
- --pd->pollers.medium;
- if (!pd->pollers.medium)
- {
- efl_del(pd->poll_medium);
- pd->poll_medium = NULL;
- }
- }
- else if (array[i].desc == EFL_LOOP_EVENT_POLL_LOW)
- {
- --pd->pollers.low;
- if (!pd->pollers.low)
- {
- efl_del(pd->poll_low);
- pd->poll_low = NULL;
- }
- }
- }
-}
-
-EFL_CALLBACKS_ARRAY_DEFINE(event_catcher_watch,
- { EFL_EVENT_CALLBACK_ADD, _check_event_catcher_add },
- { EFL_EVENT_CALLBACK_DEL, _check_event_catcher_del });
-
-EOLIAN static Efl_Object *
-_efl_loop_efl_object_constructor(Eo *obj, Efl_Loop_Data *pd)
-{
- obj = efl_constructor(efl_super(obj, EFL_LOOP_CLASS));
- if (!obj) return NULL;
-
- efl_event_callback_array_add(obj, event_catcher_watch(), pd);
-
- pd->providers = eina_hash_pointer_new(EINA_FREE_CB(efl_unref));
-
- return obj;
-}
-
-EOLIAN static void
-_efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
-{
- eina_hash_free(pd->providers);
-
- efl_del(pd->poll_low);
- efl_del(pd->poll_medium);
- efl_del(pd->poll_high);
-
- efl_destructor(efl_super(obj, EFL_LOOP_CLASS));
-}
-
-static void
-_efl_loop_arguments_cleanup(Eina_Array *arga)
-{
- Eina_Stringshare *s;
-
- while ((s = eina_array_pop(arga)))
- eina_stringshare_del(s);
- eina_array_free(arga);
-}
-
-static Eina_Value
-_efl_loop_arguments_send(void *data, const Eina_Value v,
- const Eina_Future *dead EINA_UNUSED)
-{
- static Eina_Bool initialization = EINA_TRUE;
- Efl_Loop_Arguments arge;
- Eina_Array *arga = data;
-
- if (v.type == EINA_VALUE_TYPE_ERROR)
- goto on_error;
-
- arge.argv = arga;
- arge.initialization = initialization;
- initialization = EINA_FALSE;
-
- efl_event_callback_call(ecore_main_loop_get(), EFL_LOOP_EVENT_ARGUMENTS, &arge);
-
- on_error:
- _efl_loop_arguments_cleanup(arga);
-
- return v;
-}
-
-// It doesn't make sense to send those argument to any other mainloop
-// As it also doesn't make sense to allow anyone to override this, so
-// should be internal for sure, not even protected.
-EAPI void
-ecore_loop_arguments_send(int argc, const char **argv)
-{
- Eina_Future *job;
- Eina_Array *arga;
- int i = 0;
-
- arga = eina_array_new(argc);
- for (i = 0; i < argc; i++)
- eina_array_push(arga, eina_stringshare_add(argv[i]));
-
- job = eina_future_then(efl_loop_job(ecore_main_loop_get()),
- _efl_loop_arguments_send, arga);
- efl_future_Eina_FutureXXX_then(ecore_main_loop_get(), job);
-}
-
-// 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);
-}
-
-void
-ecore_loop_promise_register(Efl_Loop *l EINA_UNUSED, Efl_Promise *p)
-{
- _pending_promises = eina_list_append(_pending_promises, p);
-}
-
-void
-ecore_loop_promise_unregister(Efl_Loop *l EINA_UNUSED, Efl_Promise *p)
-{
- _pending_promises = eina_list_remove(_pending_promises, p);
-}
-
-static Eina_Future *
-_efl_loop_job(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
-{
- // 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));
-}
-
-static void
-_efl_loop_idle_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
-{
- Efl_Loop_Promise_Simple_Data *d = data;
- ecore_idler_del(d->idler);
- efl_loop_promise_simple_data_mp_free(d);
-}
-
-static Eina_Bool
-_efl_loop_idle_done(void *data)
-{
- Efl_Loop_Promise_Simple_Data *d = data;
- eina_promise_resolve(d->promise, EINA_VALUE_EMPTY);
- efl_loop_promise_simple_data_mp_free(d);
- return EINA_FALSE;
-}
-
-static Eina_Future *
-_efl_loop_idle(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
-{
- Efl_Loop_Promise_Simple_Data *d;
- Eina_Promise *p;
-
- d = efl_loop_promise_simple_data_calloc(1);
- EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
-
- 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);
- // d is dead if p is NULL
- EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
- d->promise = p;
-
- // NOTE: Eolian should do efl_future_then() to bind future to object.
- return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));
-
- idler_error:
- efl_loop_promise_simple_data_mp_free(d);
- return NULL;
-}
-
-static void
-_efl_loop_timeout_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
-{
- Efl_Loop_Promise_Simple_Data *d = data;
- ecore_timer_del(d->timer);
- efl_loop_promise_simple_data_mp_free(d);
-}
-
-static Eina_Bool
-_efl_loop_timeout_done(void *data)
-{
- Efl_Loop_Promise_Simple_Data *d = data;
- eina_promise_resolve(d->promise, EINA_VALUE_EMPTY);
- efl_loop_promise_simple_data_mp_free(d);
- return EINA_FALSE;
-}
-
-static Eina_Future *
-_efl_loop_timeout(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, double time)
-{
- Efl_Loop_Promise_Simple_Data *d;
- Eina_Promise *p;
-
- d = efl_loop_promise_simple_data_calloc(1);
- EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
-
- d->timer = ecore_timer_add(time, _efl_loop_timeout_done, 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);
- // d is dead if p is NULL
- EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
- d->promise = p;
-
- // NOTE: Eolian should do efl_future_then() to bind future to object.
- return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));
-
- timer_error:
- efl_loop_promise_simple_data_mp_free(d);
- return NULL;
-}
-
-static Eina_Bool
-_efl_loop_register(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, const Efl_Class *klass, const Efl_Object *provider)
-{
- // The passed object does not provide that said class.
- if (!efl_isa(provider, klass)) return EINA_FALSE;
-
- // Note: I would prefer to use efl_xref here, but I can't figure a nice way to
- // call efl_xunref on hash destruction.
- return eina_hash_add(pd->providers, &klass, efl_ref(provider));
-}
-
-static Eina_Bool
-_efl_loop_unregister(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, const Efl_Class *klass, const Efl_Object *provider)
-{
- return eina_hash_del(pd->providers, &klass, provider);
-}
-
-Efl_Version _app_efl_version = { 0, 0, 0, 0, NULL, NULL };
-
-EWAPI void
-efl_build_version_set(int vmaj, int vmin, int vmic, int revision,
- const char *flavor, const char *build_id)
-{
- // note: EFL has not been initialized yet at this point (ie. no eina call)
- _app_efl_version.major = vmaj;
- _app_efl_version.minor = vmin;
- _app_efl_version.micro = vmic;
- _app_efl_version.revision = revision;
- free((char *) _app_efl_version.flavor);
- free((char *) _app_efl_version.build_id);
- _app_efl_version.flavor = flavor ? strdup(flavor) : NULL;
- _app_efl_version.build_id = build_id ? strdup(build_id) : NULL;
-}
-
-EOLIAN static const Efl_Version *
-_efl_loop_app_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
-{
- return &_app_efl_version;
-}
-
-EOLIAN static const Efl_Version *
-_efl_loop_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
-{
- /* vanilla EFL: flavor = NULL */
- static const Efl_Version version = {
- .major = VMAJ,
- .minor = VMIN,
- .micro = VMIC,
- .revision = VREV,
- .build_id = EFL_BUILD_ID,
- .flavor = NULL
- };
-
- return &version;
-}
-
-EAPI Eina_Future_Scheduler *
-efl_loop_future_scheduler_get(Eo *obj)
-{
- if (!obj) return NULL;
-
- if (efl_isa(obj, EFL_LOOP_CLASS))
- return _ecore_event_future_scheduler_get();
-
- return efl_loop_future_scheduler_get(efl_loop_get(obj));
-}
-
-#include "efl_loop.eo.c"
diff --git a/src/lib/ecore/ecore_main_common.h b/src/lib/ecore/ecore_main_common.h
new file mode 100644
index 0000000000..f015549877
--- /dev/null
+++ b/src/lib/ecore/ecore_main_common.h
@@ -0,0 +1,96 @@
+//////////////////////////////////////////////////////////////////////////
+#if defined(HAVE_SYS_EPOLL_H)
+# define HAVE_EPOLL 1
+# include <sys/epoll.h>
+#else
+
+# define HAVE_EPOLL 0
+# define EPOLLIN 1
+# define EPOLLPRI 2
+# define EPOLLOUT 4
+# define EPOLLERR 8
+
+# define EPOLL_CTL_ADD 1
+# define EPOLL_CTL_DEL 2
+# define EPOLL_CTL_MOD 3
+
+typedef union epoll_data
+{
+ void *ptr;
+ int fd;
+ uint32_t u32;
+ uint64_t u64;
+} epoll_data_t;
+
+struct epoll_event
+{
+ uint32_t events;
+ epoll_data_t data;
+};
+
+static inline int
+epoll_create(int size EINA_UNUSED)
+{
+ return -1;
+}
+
+static inline int
+epoll_wait(int epfd EINA_UNUSED,
+ struct epoll_event *events EINA_UNUSED,
+ int maxevents EINA_UNUSED,
+ int timeout EINA_UNUSED)
+{
+ return -1;
+}
+
+static inline int
+epoll_ctl(int epfd EINA_UNUSED,
+ int op EINA_UNUSED,
+ int fd EINA_UNUSED,
+ struct epoll_event *event EINA_UNUSED)
+{
+ return -1;
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+#ifdef HAVE_SYS_TIMERFD_H
+# include <sys/timerfd.h>
+#else
+/* fallback code if we don't have real timerfd - reduces number of ifdefs */
+# ifndef CLOCK_MONOTONIC
+# define CLOCK_MONOTONIC 0 /* bogus value */
+# endif
+# ifndef TFD_NONBLOCK
+# define TFD_NONBLOCK 0 /* bogus value */
+# endif
+#endif /* HAVE_SYS_TIMERFD_H */
+
+#ifndef TFD_TIMER_ABSTIME
+# define TFD_TIMER_ABSTIME (1 << 0)
+#endif
+#ifndef TFD_TIMER_CANCEL_ON_SET
+# define TFD_TIMER_CANCEL_ON_SET (1 << 1)
+#endif
+
+#ifndef TIME_T_MAX
+# define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
+#endif
+
+#ifndef HAVE_TIMERFD_CREATE
+static inline int
+timerfd_create(int clockid EINA_UNUSED,
+ int flags EINA_UNUSED)
+{
+ return -1;
+}
+
+static inline int
+timerfd_settime(int fd EINA_UNUSED,
+ int flags EINA_UNUSED,
+ const struct itimerspec *new_value EINA_UNUSED,
+ struct itimerspec *old_value EINA_UNUSED)
+{
+ return -1;
+}
+#endif /* HAVE_TIMERFD_CREATE */
diff --git a/src/lib/ecore/ecore_main_timechanges.c b/src/lib/ecore/ecore_main_timechanges.c
new file mode 100644
index 0000000000..b0f6d33b7c
--- /dev/null
+++ b/src/lib/ecore/ecore_main_timechanges.c
@@ -0,0 +1,88 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/time.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "lib/ecore/ecore_main_common.h"
+
+#ifdef HAVE_SYS_TIMERFD_H
+
+static Eo *realtime_obj = NULL;
+
+static void
+_cb_read(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ Eo *loop = efl_provider_find(event->object, EFL_LOOP_CLASS);
+ int fd = efl_loop_handler_fd_get(event->object);
+ char buf[8];
+
+ if (read(fd, buf, sizeof(buf)) >= 0) return;
+ DBG("system clock changed");
+ // XXX: ecore event needs to be eo loop api's
+ ecore_event_add(ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED, NULL, NULL, NULL);
+ _ecore_main_timechanges_stop(loop);
+ _ecore_main_timechanges_start(loop);
+}
+
+static void
+_cb_del(void *data EINA_UNUSED, const Efl_Event *event)
+{
+ int fd = efl_loop_handler_fd_get(event->object);
+ if (event->object == realtime_obj) realtime_obj = NULL;
+ close(fd);
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(_event_watch,
+ { EFL_LOOP_HANDLER_EVENT_READ, _cb_read },
+ { EFL_EVENT_DEL, _cb_del });
+#endif
+
+void
+_ecore_main_timechanges_start(Eo *obj)
+{
+#ifdef HAVE_SYS_TIMERFD_H
+ struct itimerspec its;
+ int fd;
+
+ if (realtime_obj) return;
+
+ fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC);
+ if (fd < 0) return;
+
+ memset(&its, 0, sizeof(its));
+ its.it_value.tv_sec = TIME_T_MAX; // end of time - 0xf
+ if (timerfd_settime(fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET,
+ &its, NULL) < 0)
+ {
+ WRN("Couldn't arm timerfd to detect clock changes: %s", strerror(errno));
+ close(fd);
+ return;
+ }
+ realtime_obj =
+ efl_add(EFL_LOOP_HANDLER_CLASS, obj,
+ efl_loop_handler_fd_set(efl_added, fd),
+ efl_loop_handler_active_set(efl_added, ECORE_FD_READ),
+ efl_event_callback_array_add(efl_added, _event_watch(), NULL));
+#endif
+}
+
+void
+_ecore_main_timechanges_stop(Eo *obj EINA_UNUSED)
+{
+#ifdef HAVE_SYS_TIMERFD_H
+ if (!realtime_obj) return;
+ efl_del(realtime_obj);
+ realtime_obj = NULL;
+#endif
+}
diff --git a/src/lib/ecore/ecore_pipe.c b/src/lib/ecore/ecore_pipe.c
index d85d0bf54f..c8fbb87ae4 100644
--- a/src/lib/ecore/ecore_pipe.c
+++ b/src/lib/ecore/ecore_pipe.c
@@ -56,16 +56,12 @@
#define PIPE_FD_INVALID -1
#ifdef _WIN32
-
# include <winsock2.h>
-
# define pipe_write(fd, buffer, size) send((fd), (char *)(buffer), size, 0)
# define pipe_read(fd, buffer, size) recv((fd), (char *)(buffer), size, 0)
# define pipe_close(fd) closesocket(fd)
# define PIPE_FD_ERROR SOCKET_ERROR
-
#else
-
# ifdef HAVE_SYS_EPOLL_H
# include <sys/epoll.h>
# endif /* HAVE_SYS_EPOLL_H */
@@ -74,23 +70,21 @@
# endif
# include <unistd.h>
# include <fcntl.h>
-
# define pipe_write(fd, buffer, size) write((fd), buffer, size)
# define pipe_read(fd, buffer, size) read((fd), buffer, size)
# define pipe_close(fd) close(fd)
# define PIPE_FD_ERROR -1
-
#endif /* ! _WIN32 */
#include "Ecore.h"
#include "ecore_private.h"
-/* How of then we should retry to write to the pipe */
+// How of then we should retry to write to the pipe
#define ECORE_PIPE_WRITE_RETRY 6
struct _Ecore_Pipe
{
- ECORE_MAGIC;
+ ECORE_MAGIC;
int fd_read;
int fd_write;
Ecore_Fd_Handler *fd_handler;
@@ -116,11 +110,7 @@ EAPI Ecore_Pipe *
ecore_pipe_add(Ecore_Pipe_Cb handler,
const void *data)
{
- Ecore_Pipe *p;
-
- p = _ecore_pipe_add(handler, data);
-
- return p;
+ return _ecore_pipe_add(handler, data);
}
EAPI void *
@@ -138,11 +128,11 @@ ecore_pipe_read_close(Ecore_Pipe *p)
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
{
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_close");
- return ;
+ return;
}
if (p->fd_handler)
{
- _ecore_main_fd_handler_del(p->fd_handler);
+ _ecore_main_fd_handler_del(ML_OBJ, ML_DAT, p->fd_handler);
p->fd_handler = NULL;
}
if (p->fd_read != PIPE_FD_INVALID)
@@ -166,11 +156,11 @@ ecore_pipe_freeze(Ecore_Pipe *p)
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
{
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_freeze");
- return ;
+ return;
}
if (p->fd_handler)
{
- _ecore_main_fd_handler_del(p->fd_handler);
+ _ecore_main_fd_handler_del(ML_OBJ, ML_DAT, p->fd_handler);
p->fd_handler = NULL;
}
}
@@ -182,16 +172,12 @@ ecore_pipe_thaw(Ecore_Pipe *p)
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
{
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_thaw");
- return ;
- }
- if (!p->fd_handler && p->fd_read != PIPE_FD_INVALID)
- {
- p->fd_handler = ecore_main_fd_handler_add(p->fd_read,
- ECORE_FD_READ,
- _ecore_pipe_read,
- p,
- NULL, NULL);
+ return;
}
+ if ((!p->fd_handler) && (p->fd_read != PIPE_FD_INVALID))
+ p->fd_handler = ecore_main_fd_handler_add(p->fd_read, ECORE_FD_READ,
+ _ecore_pipe_read, p,
+ NULL, NULL);
}
EAPI int
@@ -208,7 +194,7 @@ ecore_pipe_write_close(Ecore_Pipe *p)
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
{
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write_close");
- return ;
+ return;
}
if (p->fd_write != PIPE_FD_INVALID)
{
@@ -244,8 +230,7 @@ ecore_pipe_write(Ecore_Pipe *p,
if (p->fd_write == PIPE_FD_INVALID) goto out;
- /* First write the len into the pipe */
- do
+ do // First write the len into the pipe
{
ret = pipe_write(p->fd_write, &nbytes, sizeof(nbytes));
if (ret == sizeof(nbytes))
@@ -255,19 +240,19 @@ ecore_pipe_write(Ecore_Pipe *p,
}
else if (ret > 0)
{
- /* XXX What should we do here? */
- ERR("The length of the data was not written complete"
- " to the pipe");
- goto out;
+ // XXX What should we do here?
+ ERR("The length of the data was not written complete"
+ " to the pipe");
+ goto out;
}
- else if (ret == PIPE_FD_ERROR && errno == EPIPE)
+ else if ((ret == PIPE_FD_ERROR) && (errno == EPIPE))
{
pipe_close(p->fd_write);
p->fd_write = PIPE_FD_INVALID;
goto out;
}
- else if (ret == PIPE_FD_ERROR && errno == EINTR)
- /* try it again */
+ else if ((ret == PIPE_FD_ERROR) && (errno == EINTR))
+ // try it again
;
else
{
@@ -280,8 +265,7 @@ ecore_pipe_write(Ecore_Pipe *p,
if (retry != ECORE_PIPE_WRITE_RETRY) goto out;
- /* and now pass the data to the pipe */
- do
+ do // and now pass the data to the pipe
{
ret = pipe_write(p->fd_write,
((unsigned char *)buffer) + already_written,
@@ -289,22 +273,22 @@ ecore_pipe_write(Ecore_Pipe *p,
if (ret == (ssize_t)(nbytes - already_written))
{
- ok = EINA_TRUE;
- goto out;
+ ok = EINA_TRUE;
+ goto out;
}
else if (ret >= 0)
{
already_written -= ret;
continue;
}
- else if (ret == PIPE_FD_ERROR && errno == EPIPE)
+ else if ((ret == PIPE_FD_ERROR) && (errno == EPIPE))
{
pipe_close(p->fd_write);
p->fd_write = PIPE_FD_INVALID;
goto out;
}
- else if (ret == PIPE_FD_ERROR && errno == EINTR)
- /* try it again */
+ else if ((ret == PIPE_FD_ERROR) && (errno == EINTR))
+ // try it again
;
else
{
@@ -336,8 +320,7 @@ ecore_pipe_full_add(Ecore_Pipe_Cb handler,
p = ecore_pipe_calloc(1);
if (!p) return NULL;
- if (fd_read == -1 &&
- fd_write == -1)
+ if ((fd_read == -1) && (fd_write == -1))
{
if (pipe(fds))
{
@@ -349,8 +332,8 @@ ecore_pipe_full_add(Ecore_Pipe_Cb handler,
}
else
{
- fd_read = fd_read == -1 ? PIPE_FD_INVALID : fd_read;
- fd_write = fd_write == -1 ? PIPE_FD_INVALID : fd_write;
+ fd_read = (fd_read == -1) ? PIPE_FD_INVALID : fd_read;
+ fd_write = (fd_write == -1) ? PIPE_FD_INVALID : fd_write;
}
ECORE_MAGIC_SET(p, ECORE_MAGIC_PIPE);
@@ -359,10 +342,8 @@ ecore_pipe_full_add(Ecore_Pipe_Cb handler,
p->handler = handler;
p->data = data;
- if (!read_survive_fork)
- eina_file_close_on_exec(fd_read, EINA_TRUE);
- if (!write_survive_fork)
- eina_file_close_on_exec(fd_write, EINA_TRUE);
+ if (!read_survive_fork) eina_file_close_on_exec(fd_read, EINA_TRUE);
+ if (!write_survive_fork) eina_file_close_on_exec(fd_write, EINA_TRUE);
#if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_SYS_TIMERFD_H)
struct epoll_event pollev = { 0 };
@@ -381,23 +362,17 @@ ecore_pipe_full_add(Ecore_Pipe_Cb handler,
if (fcntl(p->fd_read, F_SETFL, O_NONBLOCK) < 0)
ERR("can't set pipe to NONBLOCK");
- p->fd_handler = ecore_main_fd_handler_add(p->fd_read,
- ECORE_FD_READ,
- _ecore_pipe_read,
- p,
- NULL, NULL);
-
+ p->fd_handler = ecore_main_fd_handler_add(p->fd_read, ECORE_FD_READ,
+ _ecore_pipe_read, p, NULL, NULL);
return p;
}
-/* Private functions */
+// Private functions
Ecore_Pipe *
_ecore_pipe_add(Ecore_Pipe_Cb handler,
const void *data)
{
- return ecore_pipe_full_add(handler, data,
- -1, -1,
- EINA_FALSE, EINA_FALSE);
+ return ecore_pipe_full_add(handler, data, -1, -1, EINA_FALSE, EINA_FALSE);
}
void *
@@ -420,7 +395,8 @@ _ecore_pipe_del(Ecore_Pipe *p)
#endif
p->delete_me = EINA_TRUE;
if (p->handling > 0) return (void *)p->data;
- if (p->fd_handler) _ecore_main_fd_handler_del(p->fd_handler);
+ if (p->fd_handler) _ecore_main_fd_handler_del(ML_OBJ, ML_DAT,
+ p->fd_handler);
if (p->fd_read != PIPE_FD_INVALID) pipe_close(p->fd_read);
if (p->fd_write != PIPE_FD_INVALID) pipe_close(p->fd_write);
p->fd_handler = NULL;
@@ -435,10 +411,7 @@ static void
_ecore_pipe_unhandle(Ecore_Pipe *p)
{
p->handling--;
- if (p->delete_me)
- {
- _ecore_pipe_del(p);
- }
+ if (p->delete_me) _ecore_pipe_del(p);
}
#if ! defined(HAVE_SYS_EPOLL_H) || ! defined(HAVE_SYS_TIMERFD_H)
@@ -455,23 +428,21 @@ _ecore_pipe_wait(Ecore_Pipe *p,
int total = 0;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1);
- if (p->fd_read == PIPE_FD_INVALID)
- return -1;
+ if (p->fd_read == PIPE_FD_INVALID) return -1;
FD_ZERO(&rset);
FD_ZERO(&wset);
FD_ZERO(&exset);
FD_SET(p->fd_read, &rset);
- if (wait >= 0.0)
- end = ecore_time_get() + wait;
+ if (wait >= 0.0) end = ecore_time_get() + wait;
timeout = wait;
- while (message_count > 0 && (timeout > 0.0 || wait <= 0.0))
+ while ((message_count > 0) && ((timeout > 0.0) || (wait <= 0.0)))
{
if (wait >= 0.0)
{
- /* finite() tests for NaN, too big, too small, and infinity. */
+ // finite() tests for NaN, too big, too small, and infinity.
if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0)))
{
tv.tv_sec = 0;
@@ -490,10 +461,7 @@ _ecore_pipe_wait(Ecore_Pipe *p,
}
t = &tv;
}
- else
- {
- t = NULL;
- }
+ else t = NULL;
ret = main_loop_select(p->fd_read + 1, &rset, &wset, &exset, t);
@@ -506,10 +474,7 @@ _ecore_pipe_wait(Ecore_Pipe *p,
p->message = 0;
_ecore_pipe_unhandle(p);
}
- else if (ret == 0)
- {
- break;
- }
+ else if (ret == 0) break;
else if (errno != EINTR)
{
if (p->fd_read != PIPE_FD_INVALID)
@@ -520,8 +485,7 @@ _ecore_pipe_wait(Ecore_Pipe *p,
break;
}
- if (wait >= 0.0)
- timeout = end - ecore_time_get();
+ if (wait >= 0.0) timeout = end - ecore_time_get();
}
return total;
@@ -538,18 +502,17 @@ _ecore_pipe_wait(Ecore_Pipe *p,
double timeout;
int ret;
int total = 0;
- int time_exit=-1;
+ int time_exit = -1;
Eina_Bool fd_read_found;
Eina_Bool fd_timer_found;
struct itimerspec tspec_new;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1);
- if (p->fd_read == PIPE_FD_INVALID)
- return -1;
+ if (p->fd_read == PIPE_FD_INVALID) return -1;
timeout = wait;
int sec, usec;
- if ( wait >= 0.0)
+ if (wait >= 0.0)
{
if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0)))
{
@@ -571,45 +534,45 @@ _ecore_pipe_wait(Ecore_Pipe *p,
tspec_new.it_interval.tv_sec = 0;
tspec_new.it_interval.tv_nsec = 0;
timerfd_settime(p->timerfd, 0, &tspec_new, NULL);
- }
+ }
}
while ((ret = epoll_wait(p->pollfd, pollincoming, 2, time_exit)) > 0)
{
- fd_read_found = EINA_FALSE;
- fd_timer_found = EINA_FALSE;
-
- for (int i = 0; i < ret;i++)
- {
- if ((&p->fd_read == pollincoming[i].data.ptr))
- fd_read_found = EINA_TRUE;
- if ((&p->timerfd == pollincoming[i].data.ptr))
- fd_timer_found = EINA_TRUE;
- }
-
- p->handling++;
- if (fd_read_found)
- {
- _ecore_pipe_read(p, NULL);
- message_count -= p->message;
- total += p->message;
- p->message = 0;
- if (message_count <= 0)
- {
- _ecore_pipe_unhandle(p);
- break;
- }
- }
-
- if ((fd_timer_found) && (p->timerfd != PIPE_FD_INVALID))
- {
- if (pipe_read(p->timerfd, &timerfdbuf, sizeof(timerfdbuf))
- < (int)sizeof(int64_t))
- WRN("Could not read timerfd data");
- _ecore_pipe_unhandle(p);
- break;
- }
- _ecore_pipe_unhandle(p);
+ fd_read_found = EINA_FALSE;
+ fd_timer_found = EINA_FALSE;
+
+ for (int i = 0; i < ret;i++)
+ {
+ if ((&p->fd_read == pollincoming[i].data.ptr))
+ fd_read_found = EINA_TRUE;
+ if ((&p->timerfd == pollincoming[i].data.ptr))
+ fd_timer_found = EINA_TRUE;
+ }
+
+ p->handling++;
+ if (fd_read_found)
+ {
+ _ecore_pipe_read(p, NULL);
+ message_count -= p->message;
+ total += p->message;
+ p->message = 0;
+ if (message_count <= 0)
+ {
+ _ecore_pipe_unhandle(p);
+ break;
+ }
+ }
+
+ if ((fd_timer_found) && (p->timerfd != PIPE_FD_INVALID))
+ {
+ if (pipe_read(p->timerfd, &timerfdbuf, sizeof(timerfdbuf)) <
+ (int)sizeof(int64_t))
+ WRN("Could not read timerfd data");
+ _ecore_pipe_unhandle(p);
+ break;
+ }
+ _ecore_pipe_unhandle(p);
}
if (ret < 0)
{
@@ -623,7 +586,6 @@ _ecore_pipe_wait(Ecore_Pipe *p,
WRN("The call was interrupted by a signal handler before any of the requested epoll_event "
"occurred or the timeout expired; see signal(7).");
}
-
return total;
}
@@ -641,10 +603,7 @@ _ecore_pipe_handler_call(Ecore_Pipe *p,
p->len = 0;
p->message++;
- if (!p->delete_me)
- {
- p->handler(data, buf, len);
- }
+ if (!p->delete_me) p->handler(data, buf, len);
// free p->passed_data
free(buf);
@@ -662,64 +621,63 @@ _ecore_pipe_read(void *data,
{
ssize_t ret;
- /* if we already have read some data we don't need to read the len
- * but to finish the already started job
- */
+ // if we already have read some data we don't need to read the len
+ // but to finish the already started job
if (p->len == 0)
{
- /* read the len of the passed data */
- ret = pipe_read(p->fd_read, &p->len, sizeof(p->len));
-
- /* catch the non error case first */
- /* read amount ok - nothing more to do */
- if (ret == sizeof(p->len))
- ;
- else if (ret > 0)
- {
- /* we got more data than we asked for - definite error */
- ERR("Only read %i bytes from the pipe, although"
- " we need to read %i bytes.",
- (int)ret, (int)sizeof(p->len));
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_CANCEL;
- }
- else if (ret == 0)
- {
- /* we got no data */
- if (i == 0)
- {
- /* no data on first try through means an error */
- _ecore_pipe_handler_call(p, NULL, 0);
- pipe_close(p->fd_read);
- p->fd_read = PIPE_FD_INVALID;
- p->fd_handler = NULL;
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_CANCEL;
- }
- else
- {
- /* no data after first loop try is ok */
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_RENEW;
- }
- }
+ // read the len of the passed data
+ ret = pipe_read(p->fd_read, &p->len, sizeof(p->len));
+
+ // catch the non error case first
+ // read amount ok - nothing more to do
+ if (ret == sizeof(p->len))
+ ;
+ else if (ret > 0)
+ {
+ // we got more data than we asked for - definite error
+ ERR("Only read %i bytes from the pipe, although"
+ " we need to read %i bytes.",
+ (int)ret, (int)sizeof(p->len));
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_CANCEL;
+ }
+ else if (ret == 0)
+ {
+ // we got no data
+ if (i == 0)
+ {
+ // no data on first try through means an error
+ _ecore_pipe_handler_call(p, NULL, 0);
+ pipe_close(p->fd_read);
+ p->fd_read = PIPE_FD_INVALID;
+ p->fd_handler = NULL;
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_CANCEL;
+ }
+ else
+ {
+ // no data after first loop try is ok
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_RENEW;
+ }
+ }
#ifndef _WIN32
- else if ((ret == PIPE_FD_ERROR) &&
- ((errno == EINTR) || (errno == EAGAIN)))
+ else if ((ret == PIPE_FD_ERROR) &&
+ ((errno == EINTR) || (errno == EAGAIN)))
{
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_RENEW;
- }
- else
- {
- ERR("An unhandled error (ret: %i errno: %i [%s])"
- "occurred while reading from the pipe the length",
- (int)ret, errno, strerror(errno));
- _ecore_pipe_unhandle(p);
+ _ecore_pipe_unhandle(p);
return ECORE_CALLBACK_RENEW;
}
+ else
+ {
+ ERR("An unhandled error (ret: %i errno: %i [%s])"
+ "occurred while reading from the pipe the length",
+ (int)ret, errno, strerror(errno));
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_RENEW;
+ }
#else
- else /* ret == PIPE_FD_ERROR is the only other case on Windows */
+ else // ret == PIPE_FD_ERROR is the only other case on Windows
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
@@ -733,10 +691,9 @@ _ecore_pipe_read(void *data,
}
#endif
}
-
- /* if somehow we got less than or equal to 0 we got an errnoneous
- * messages so call callback with null and len we got. this case should
- * never happen */
+ // if somehow we got less than or equal to 0 we got an errnoneous
+ // messages so call callback with null and len we got. this case should
+ // never happen
if (p->len == 0)
{
_ecore_pipe_handler_call(p, NULL, 0);
@@ -744,15 +701,15 @@ _ecore_pipe_read(void *data,
return ECORE_CALLBACK_RENEW;
}
- /* we dont have a buffer to hold the data, so alloc it */
+ // we dont have a buffer to hold the data, so alloc it
if (!p->passed_data)
{
p->passed_data = malloc(p->len);
- /* alloc failed - error case */
+ // alloc failed - error case
if (!p->passed_data)
{
_ecore_pipe_handler_call(p, NULL, 0);
- /* close the pipe */
+ // close the pipe
pipe_close(p->fd_read);
p->fd_read = PIPE_FD_INVALID;
p->fd_handler = NULL;
@@ -761,27 +718,27 @@ _ecore_pipe_read(void *data,
}
}
- /* and read the passed data */
+ // and read the passed data
ret = pipe_read(p->fd_read,
((unsigned char *)p->passed_data) + p->already_read,
p->len - p->already_read);
- /* catch the non error case first */
- /* if we read enough data to finish the message/buffer */
+ // catch the non error case first
+ // if we read enough data to finish the message/buffer
if (ret == (ssize_t)(p->len - p->already_read))
_ecore_pipe_handler_call(p, p->passed_data, p->len);
else if (ret > 0)
{
- /* more data left to read */
- p->already_read += (unsigned int) ret;
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_RENEW;
+ // more data left to read
+ p->already_read += (unsigned int)ret;
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_RENEW;
}
else if (ret == 0)
{
- /* 0 bytes to read - could be more to read next select wake up */
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_RENEW;
+ // 0 bytes to read - could be more to read next select wake up
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_RENEW;
}
#ifndef _WIN32
else if ((ret == PIPE_FD_ERROR) &&
@@ -799,7 +756,7 @@ _ecore_pipe_read(void *data,
return ECORE_CALLBACK_RENEW;
}
#else
- else /* ret == PIPE_FD_ERROR is the only other case on Windows */
+ else // ret == PIPE_FD_ERROR is the only other case on Windows
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
@@ -810,8 +767,7 @@ _ecore_pipe_read(void *data,
_ecore_pipe_unhandle(p);
return ECORE_CALLBACK_CANCEL;
}
- else
- break;
+ else break;
}
#endif
}
diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h
index 366c169943..d9a44ce989 100644
--- a/src/lib/ecore/ecore_private.h
+++ b/src/lib/ecore/ecore_private.h
@@ -83,22 +83,84 @@ 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_Data Efl_Loop_Data;
+
+typedef struct _Message_Handler Message_Handler;
+typedef struct _Message Message;
+
+struct _Message_Handler
+{
+ Eo *handler;
+ const Eo *klass;
+};
+
+struct _Message
+{
+ EINA_INLIST;
+ Eo *handler;
+ Eo *message;
+ Eina_Bool delete_me;
+};
+
struct _Efl_Loop_Data
{
- Eina_Hash *providers;
+ double loop_time;
+ Eina_Hash *providers;
+
+ Ecore_Timer *poll_high;
+ Ecore_Timer *poll_medium;
+ Ecore_Timer *poll_low;
+
+ Eina_List *exes; // only used in main loop (for now?)
+
+ Eina_List *fd_handlers_obj;
+
+ Ecore_Fd_Handler *fd_handlers;
+ Eina_List *fd_handlers_with_prep;
+ Eina_List *file_fd_handlers;
+ Eina_List *fd_handlers_with_buffer;
+ Eina_List *fd_handlers_to_delete;
+ Ecore_Fd_Handler *fd_handlers_to_call;
+ Ecore_Fd_Handler *fd_handlers_to_call_current;
+
+# ifdef _WIN32
+ Ecore_Win32_Handler *win32_handlers;
+ Ecore_Win32_Handler *win32_handler_current;
+ Eina_List *win32_handlers_to_delete;
+# endif
+
+ Eina_List *pending_futures;
+ Eina_List *pending_promises;
- Ecore_Timer *poll_high;
- Ecore_Timer *poll_medium;
- Ecore_Timer *poll_low;
+ Eina_Inarray *message_handlers;
+ Eina_Inlist *message_queue;
+ unsigned int message_walking;
- int idlers;
+ unsigned int throttle;
+
+ int epoll_fd;
+ pid_t epoll_pid;
+ int timer_fd;
+
+ double last_check;
+ Eina_Inlist *timers;
+ Eina_Inlist *suspended;
+ Efl_Loop_Timer_Data *timer_current;
+ int timers_added;
+
+ Eina_Value exit_code;
+
+ int idlers;
+ int in_loop;
struct {
- int high;
- int medium;
- int low;
+ int high;
+ int medium;
+ int low;
} pollers;
+
+ Eina_Bool do_quit;
};
#define EVAS_FRAME_QUEUING 1 /* for test */
@@ -167,13 +229,11 @@ EAPI void _ecore_magic_fail(const void *d,
void _ecore_time_init(void);
void *_efl_loop_timer_del(Ecore_Timer *timer);
-void _efl_loop_timer_shutdown(void);
-void _efl_loop_timer_enable_new(void);
-double _efl_loop_timer_next_get(void);
-void _efl_loop_timer_expired_timers_call(double when);
-int _efl_loop_timers_exists(void);
-
-int _efl_loop_timer_expired_call(double when);
+void _efl_loop_timer_enable_new(Eo *obj, Efl_Loop_Data *pd);
+double _efl_loop_timer_next_get(Eo *obj, Efl_Loop_Data *pd);
+void _efl_loop_timer_expired_timers_call(Eo *obj, Efl_Loop_Data *pd, double when);
+int _efl_loop_timers_exists(Eo *obj, Efl_Loop_Data *pd);
+int _efl_loop_timer_expired_call(Eo *obj, Efl_Loop_Data *pd, double when);
Ecore_Factorized_Idle *_ecore_factorized_idle_add(const Efl_Callback_Array_Item*desc,
Ecore_Task_Cb func,
@@ -200,7 +260,6 @@ Ecore_Event *_ecore_event_add(int type,
Ecore_End_Cb func_free,
void *data);
void _ecore_event_call(void);
-void *_ecore_event_handler_del(Ecore_Event_Handler *event_handler);
Ecore_Timer *_ecore_exe_doomsday_clock_get(Ecore_Exe *exe);
void _ecore_exe_doomsday_clock_set(Ecore_Exe *exe,
@@ -219,16 +278,32 @@ int _ecore_pipe_wait(Ecore_Pipe *p,
double wait);
void *_ecore_pipe_del(Ecore_Pipe *p);
-Ecore_Fd_Handler *
- _ecore_main_fd_handler_add(int fd,
- Ecore_Fd_Handler_Flags flags,
- Ecore_Fd_Cb func,
- const void *data,
- Ecore_Fd_Cb buf_func,
- const void *buf_data,
- Eina_Bool is_file);
-void *_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler);
-
+Ecore_Fd_Handler *_ecore_main_fd_handler_add(Eo *obj,
+ Efl_Loop_Data *pd,
+ Eo *handler,
+ int fd,
+ Ecore_Fd_Handler_Flags flags,
+ Ecore_Fd_Cb func,
+ const void *data,
+ Ecore_Fd_Cb buf_func,
+ const void *buf_data,
+ Eina_Bool is_file);
+void *_ecore_main_fd_handler_del(Eo *obj,
+ Efl_Loop_Data *pd,
+ Ecore_Fd_Handler *fd_handler);
+Ecore_Win32_Handler *
+_ecore_main_win32_handler_add(Eo *obj,
+ Efl_Loop_Data *pd,
+ Eo *handler,
+ void *h,
+ Ecore_Win32_Handle_Cb func,
+ const void *data);
+void *
+_ecore_main_win32_handler_del(Eo *obj,
+ Efl_Loop_Data *pd,
+ Ecore_Win32_Handler *win32_handler);
+
+void _ecore_main_content_clear(Efl_Loop_Data *pd);
void _ecore_main_shutdown(void);
#if defined (_WIN32) || defined (__lv2ppu__) || defined (HAVE_EXOTIC)
@@ -236,18 +311,18 @@ static inline void _ecore_signal_shutdown(void) { }
static inline void _ecore_signal_init(void) { }
-static inline void _ecore_signal_received_process(void) { }
+static inline void _ecore_signal_received_process(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) { }
-static inline int _ecore_signal_count_get(void) { return 0; }
+static inline int _ecore_signal_count_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) { return 0; }
-static inline void _ecore_signal_call(void) { }
+static inline void _ecore_signal_call(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) { }
#else
void _ecore_signal_shutdown(void);
void _ecore_signal_init(void);
-void _ecore_signal_received_process(void);
-int _ecore_signal_count_get(void);
-void _ecore_signal_call(void);
+void _ecore_signal_received_process(Eo *obj, Efl_Loop_Data *pd);
+int _ecore_signal_count_get(Eo *obj, Efl_Loop_Data *pd);
+void _ecore_signal_call(Eo *obj, Efl_Loop_Data *pd);
#endif
void _ecore_exe_init(void);
@@ -283,6 +358,11 @@ void _ecore_job_shutdown(void);
void _ecore_main_loop_init(void);
void _ecore_main_loop_shutdown(void);
+void _ecore_main_loop_iterate(Eo *obj, Efl_Loop_Data *pd);
+int _ecore_main_loop_iterate_may_block(Eo *obj, Efl_Loop_Data *pd, int may_block);
+void _ecore_main_loop_begin(Eo *obj, Efl_Loop_Data *pd);
+void _ecore_main_loop_quit(Eo *obj, Efl_Loop_Data *pd);
+
void _ecore_coroutine_init(void);
void _ecore_coroutine_shutdown(void);
@@ -290,6 +370,17 @@ void _ecore_throttle(void);
void _ecore_main_call_flush(void);
+void _ecore_main_timechanges_start(Eo *obj);
+void _ecore_main_timechanges_stop(Eo *obj);
+
+Eina_Bool _ecore_event_do_filter(void *handler_pd, Eo *msg_handler, Eo *msg);
+void _ecore_event_filters_call(Eo *obj, Efl_Loop_Data *pd);
+void _efl_loop_messages_filter(Eo *obj, Efl_Loop_Data *pd, void *handler_pd);
+void _efl_loop_messages_call(Eo *obj, Efl_Loop_Data *pd, void *func, void *data);
+
+void _efl_loop_message_send_info_set(Eo *obj, Eina_Inlist *node, Eo *loop, Efl_Loop_Data *loop_data);
+void _efl_loop_message_unsend(Eo *obj);
+
static inline Eina_Bool
_ecore_call_task_cb(Ecore_Task_Cb func,
void *data)
@@ -348,7 +439,6 @@ _ecore_call_fd_cb(Ecore_Fd_Cb func,
}
extern int _ecore_fps_debug;
-extern double _ecore_time_loop_time;
extern Eina_Bool _ecore_glib_always_integrate;
extern Ecore_Select_Function main_loop_select;
extern int in_main_loop;
@@ -362,9 +452,9 @@ void ecore_mempool_shutdown(void);
size_t _ecore_sizeof_##TYPE = sizeof (TYPE);
//GENERIC_ALLOC_FREE_HEADER(Ecore_Animator, ecore_animator);
-GENERIC_ALLOC_FREE_HEADER(Ecore_Event_Handler, ecore_event_handler);
-GENERIC_ALLOC_FREE_HEADER(Ecore_Event_Filter, ecore_event_filter);
-GENERIC_ALLOC_FREE_HEADER(Ecore_Event, ecore_event);
+//GENERIC_ALLOC_FREE_HEADER(Ecore_Event_Handler, ecore_event_handler);
+//GENERIC_ALLOC_FREE_HEADER(Ecore_Event_Filter, ecore_event_filter);
+//GENERIC_ALLOC_FREE_HEADER(Ecore_Event, ecore_event);
//GENERIC_ALLOC_FREE_HEADER(Ecore_Idle_Exiter, ecore_idle_exiter);
//GENERIC_ALLOC_FREE_HEADER(Ecore_Idle_Enterer, ecore_idle_enterer);
//GENERIC_ALLOC_FREE_HEADER(Ecore_Idler, ecore_idler);
@@ -381,6 +471,11 @@ GENERIC_ALLOC_FREE_HEADER(Ecore_Win32_Handler, ecore_win32_handler);
#undef GENERIC_ALLOC_FREE_HEADER
extern Eo *_mainloop_singleton;
+extern Efl_Loop_Data *_mainloop_singleton_data;
+#define ML_OBJ _mainloop_singleton
+#define ML_DAT _mainloop_singleton_data
+//#define ML_DAT efl_data_scope_get(ML_OBJ, EFL_LOOP_CLASS)
+
extern Efl_Version _app_efl_version;
void ecore_loop_future_register(Efl_Loop *l, Efl_Future *f);
@@ -392,6 +487,9 @@ void ecore_loop_promise_fulfill(Efl_Promise *p);
// access to direct input cb
#define ECORE_EVAS_INTERNAL
+#define EFL_LOOP_DATA efl_data_scope_get(efl_loop_main_get(EFL_LOOP_CLASS), EFL_LOOP_CLASS)
+
+
#undef EAPI
#define EAPI
diff --git a/src/lib/ecore/ecore_signal.c b/src/lib/ecore/ecore_signal.c
index 795dab439f..450342a2c7 100644
--- a/src/lib/ecore/ecore_signal.c
+++ b/src/lib/ecore/ecore_signal.c
@@ -57,27 +57,27 @@ static Eina_Bool _ecore_signal_exe_exit_delay(void *data);
//#define MAXSIGQ 256 // 32k
#define MAXSIGQ 64 // 8k
-static volatile sig_atomic_t sig_count = 0;
+static volatile sig_atomic_t sig_count = 0;
static volatile sig_atomic_t sigchld_count = 0;
static volatile sig_atomic_t sigusr1_count = 0;
static volatile sig_atomic_t sigusr2_count = 0;
-static volatile sig_atomic_t sighup_count = 0;
+static volatile sig_atomic_t sighup_count = 0;
static volatile sig_atomic_t sigquit_count = 0;
-static volatile sig_atomic_t sigint_count = 0;
+static volatile sig_atomic_t sigint_count = 0;
static volatile sig_atomic_t sigterm_count = 0;
#ifdef SIGPWR
-static volatile sig_atomic_t sigpwr_count = 0;
+static volatile sig_atomic_t sigpwr_count = 0;
#endif
static volatile siginfo_t sigchld_info[MAXSIGQ];
static volatile siginfo_t sigusr1_info[MAXSIGQ];
static volatile siginfo_t sigusr2_info[MAXSIGQ];
-static volatile siginfo_t sighup_info[MAXSIGQ];
+static volatile siginfo_t sighup_info [MAXSIGQ];
static volatile siginfo_t sigquit_info[MAXSIGQ];
-static volatile siginfo_t sigint_info[MAXSIGQ];
+static volatile siginfo_t sigint_info [MAXSIGQ];
static volatile siginfo_t sigterm_info[MAXSIGQ];
#ifdef SIGPWR
-static volatile siginfo_t sigpwr_info[MAXSIGQ];
+static volatile siginfo_t sigpwr_info [MAXSIGQ];
#endif
#if defined(SIG_ATOMIC_MAX)
@@ -108,22 +108,22 @@ _ecore_signal_shutdown(void)
_ecore_signal_callback_set(SIGCHLD, (Signal_Handler)SIG_DFL);
_ecore_signal_callback_set(SIGUSR1, (Signal_Handler)SIG_DFL);
_ecore_signal_callback_set(SIGUSR2, (Signal_Handler)SIG_DFL);
- _ecore_signal_callback_set(SIGHUP, (Signal_Handler)SIG_DFL);
+ _ecore_signal_callback_set(SIGHUP, (Signal_Handler)SIG_DFL);
_ecore_signal_callback_set(SIGQUIT, (Signal_Handler)SIG_DFL);
- _ecore_signal_callback_set(SIGINT, (Signal_Handler)SIG_DFL);
+ _ecore_signal_callback_set(SIGINT, (Signal_Handler)SIG_DFL);
_ecore_signal_callback_set(SIGTERM, (Signal_Handler)SIG_DFL);
#ifdef SIGPWR
- _ecore_signal_callback_set(SIGPWR, (Signal_Handler)SIG_DFL);
- sigpwr_count = 0;
+ _ecore_signal_callback_set(SIGPWR, (Signal_Handler)SIG_DFL);
+ sigpwr_count = 0;
#endif
sigchld_count = 0;
sigusr1_count = 0;
sigusr2_count = 0;
- sighup_count = 0;
+ sighup_count = 0;
sigquit_count = 0;
- sigint_count = 0;
+ sigint_count = 0;
sigterm_count = 0;
- sig_count = 0;
+ sig_count = 0;
}
void
@@ -134,36 +134,35 @@ _ecore_signal_init(void)
_ecore_signal_callback_set(SIGCHLD, _ecore_signal_callback_sigchld);
_ecore_signal_callback_set(SIGUSR1, _ecore_signal_callback_sigusr1);
_ecore_signal_callback_set(SIGUSR2, _ecore_signal_callback_sigusr2);
- _ecore_signal_callback_set(SIGHUP, _ecore_signal_callback_sighup);
+ _ecore_signal_callback_set(SIGHUP, _ecore_signal_callback_sighup);
_ecore_signal_callback_set(SIGQUIT, _ecore_signal_callback_sigquit);
- _ecore_signal_callback_set(SIGINT, _ecore_signal_callback_sigint);
+ _ecore_signal_callback_set(SIGINT, _ecore_signal_callback_sigint);
_ecore_signal_callback_set(SIGTERM, _ecore_signal_callback_sigterm);
#ifdef SIGPWR
- _ecore_signal_callback_set(SIGPWR, _ecore_signal_callback_sigpwr);
+ _ecore_signal_callback_set(SIGPWR, _ecore_signal_callback_sigpwr);
#endif
}
void
-_ecore_signal_received_process(void)
+_ecore_signal_received_process(Eo *obj, Efl_Loop_Data *pd)
{
- while (_ecore_signal_count_get()) _ecore_signal_call();
+ while (_ecore_signal_count_get(obj, pd)) _ecore_signal_call(obj, pd);
}
int
-_ecore_signal_count_get(void)
+_ecore_signal_count_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
{
return sig_count;
}
static void
-_ecore_signal_generic_free(void *data EINA_UNUSED,
- void *event)
+_ecore_signal_generic_free(void *data EINA_UNUSED, void *event)
{
free(event);
}
void
-_ecore_signal_call(void)
+_ecore_signal_call(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
{
volatile sig_atomic_t n;
sigset_t oldset, newset;
@@ -233,7 +232,9 @@ _ecore_signal_call(void)
if ((n < MAXSIGQ) && (sigchld_info[n].si_signo))
e->data = sigchld_info[n]; /* No need to clone this. */
- if ((e->exe) && (ecore_exe_flags_get(e->exe) & (ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR)))
+ if ((e->exe) &&
+ (ecore_exe_flags_get(e->exe) &
+ (ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR)))
{
/* We want to report the Last Words of the exe, so delay this event.
* This is twice as relevant for stderr.
@@ -257,18 +258,18 @@ _ecore_signal_call(void)
* check to see for Last Words, and only delay if there are any.
* This has it's own set of problems.
*/
- Ecore_Timer *doomsday_clock;
+ Ecore_Timer *doomsday_clock;
- doomsday_clock = _ecore_exe_doomsday_clock_get(e->exe);
- IF_FN_DEL(ecore_timer_del, doomsday_clock);
- doomsday_clock = ecore_timer_add
- (0.1, _ecore_signal_exe_exit_delay, e);
- _ecore_exe_doomsday_clock_set(e->exe, doomsday_clock);
+ doomsday_clock = _ecore_exe_doomsday_clock_get(e->exe);
+ IF_FN_DEL(ecore_timer_del, doomsday_clock);
+ doomsday_clock = ecore_timer_add
+ (0.1, _ecore_signal_exe_exit_delay, e);
+ _ecore_exe_doomsday_clock_set(e->exe, doomsday_clock);
}
else
{
- _ecore_event_add(ECORE_EXE_EVENT_DEL, e,
- _ecore_exe_event_del_free, NULL);
+ ecore_event_add(ECORE_EXE_EVENT_DEL, e,
+ _ecore_exe_event_del_free, NULL);
}
}
}
@@ -291,8 +292,8 @@ _ecore_signal_call(void)
if ((n < MAXSIGQ) && (sigusr1_info[n].si_signo))
e->data = sigusr1_info[n];
- _ecore_event_add(ECORE_EVENT_SIGNAL_USER, e,
- _ecore_signal_generic_free, NULL);
+ ecore_event_add(ECORE_EVENT_SIGNAL_USER, e,
+ _ecore_signal_generic_free, NULL);
}
sig_count--;
}
@@ -313,8 +314,8 @@ _ecore_signal_call(void)
if ((n < MAXSIGQ) && (sigusr2_info[n].si_signo))
e->data = sigusr2_info[n];
- _ecore_event_add(ECORE_EVENT_SIGNAL_USER, e,
- _ecore_signal_generic_free, NULL);
+ ecore_event_add(ECORE_EVENT_SIGNAL_USER, e,
+ _ecore_signal_generic_free, NULL);
}
sig_count--;
}
@@ -333,8 +334,8 @@ _ecore_signal_call(void)
if ((n < MAXSIGQ) && (sighup_info[n].si_signo))
e->data = sighup_info[n];
- _ecore_event_add(ECORE_EVENT_SIGNAL_HUP, e,
- _ecore_signal_generic_free, NULL);
+ ecore_event_add(ECORE_EVENT_SIGNAL_HUP, e,
+ _ecore_signal_generic_free, NULL);
}
sig_count--;
}
@@ -355,8 +356,8 @@ _ecore_signal_call(void)
if ((n < MAXSIGQ) && (sigquit_info[n].si_signo))
e->data = sigquit_info[n];
- _ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e,
- _ecore_signal_generic_free, NULL);
+ ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e,
+ _ecore_signal_generic_free, NULL);
}
sig_count--;
}
@@ -377,8 +378,8 @@ _ecore_signal_call(void)
if ((n < MAXSIGQ) && (sigint_info[n].si_signo))
e->data = sigint_info[n];
- _ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e,
- _ecore_signal_generic_free, NULL);
+ ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e,
+ _ecore_signal_generic_free, NULL);
}
sig_count--;
}
@@ -399,8 +400,8 @@ _ecore_signal_call(void)
if ((n < MAXSIGQ) && (sigterm_info[n].si_signo))
e->data = sigterm_info[n];
- _ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e,
- _ecore_signal_generic_free, NULL);
+ ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e,
+ _ecore_signal_generic_free, NULL);
}
sig_count--;
}
@@ -420,15 +421,15 @@ _ecore_signal_call(void)
if ((n < MAXSIGQ) && (sigpwr_info[n].si_signo))
e->data = sigpwr_info[n];
- _ecore_event_add(ECORE_EVENT_SIGNAL_POWER, e,
- _ecore_signal_generic_free, NULL);
+ ecore_event_add(ECORE_EVENT_SIGNAL_POWER, e,
+ _ecore_signal_generic_free, NULL);
}
sig_count--;
}
sigpwr_count = 0;
#endif
sig_count = 0;
-
+
sigprocmask(SIG_SETMASK, &oldset, NULL);
eina_evlog("-signals", NULL, 0.0, NULL);
}
@@ -609,8 +610,8 @@ _ecore_signal_exe_exit_delay(void *data)
if (e)
{
_ecore_exe_doomsday_clock_set(e->exe, NULL);
- _ecore_event_add(ECORE_EXE_EVENT_DEL, e,
- _ecore_exe_event_del_free, NULL);
+ ecore_event_add(ECORE_EXE_EVENT_DEL, e,
+ _ecore_exe_event_del_free, NULL);
}
return ECORE_CALLBACK_CANCEL;
}
diff --git a/src/lib/ecore/ecore_time.c b/src/lib/ecore/ecore_time.c
index 1fafd62179..e96e80a9f5 100644
--- a/src/lib/ecore/ecore_time.c
+++ b/src/lib/ecore/ecore_time.c
@@ -24,7 +24,6 @@ static Eina_Bool _ecore_time_got_clock_id = EINA_FALSE;
#elif defined(__APPLE__) && defined(__MACH__)
static double _ecore_time_clock_conversion = 1e-9;
#endif
-double _ecore_time_loop_time = -1.0;
EAPI double
ecore_time_get(void)
@@ -37,9 +36,9 @@ ecore_time_get(void)
if (EINA_UNLIKELY(clock_gettime(_ecore_time_clock_id, &t)))
{
- CRI("Cannot get current time.");
- /* Try to at least return the latest value retrieved*/
- return _ecore_time_loop_time;
+ CRI("Cannot get current time");
+ // Try to at least return the latest value retrieved
+ return ecore_loop_time_get();
}
return (double)t.tv_sec + (((double)t.tv_nsec) / 1000000000.0);
@@ -68,13 +67,13 @@ ecore_time_unix_get(void)
EAPI double
ecore_loop_time_get(void)
{
- return _ecore_time_loop_time;
+ return efl_loop_time_get(ML_OBJ);
}
EAPI void
ecore_loop_time_set(double t)
{
- _ecore_time_loop_time = t;
+ efl_loop_time_set(ML_OBJ, t);
}
/*-******************** Internal methods ********************************/
@@ -86,7 +85,7 @@ ecore_loop_time_set(double t)
void
_ecore_time_init(void)
{
-#if defined (HAVE_CLOCK_GETTIME) || defined (EXOTIC_PROVIDE_CLOCK_GETTIME)
+#if defined(HAVE_CLOCK_GETTIME) || defined(EXOTIC_PROVIDE_CLOCK_GETTIME)
struct timespec t;
if (_ecore_time_got_clock_id) return;
@@ -95,41 +94,32 @@ _ecore_time_init(void)
{
_ecore_time_clock_id = CLOCK_MONOTONIC;
_ecore_time_got_clock_id = EINA_TRUE;
- DBG("using CLOCK_MONOTONIC.");
+ DBG("using CLOCK_MONOTONIC");
}
else if (!clock_gettime(CLOCK_REALTIME, &t))
{
- /* may go backwards */
- _ecore_time_clock_id = CLOCK_REALTIME;
- _ecore_time_got_clock_id = EINA_TRUE;
- WRN("CLOCK_MONOTONIC not available. Fallback to CLOCK_REALTIME.");
+ // may go backwards
+ _ecore_time_clock_id = CLOCK_REALTIME;
+ _ecore_time_got_clock_id = EINA_TRUE;
+ WRN("CLOCK_MONOTONIC not available. Fallback to CLOCK_REALTIME");
}
else
- {
- CRI("Cannot get a valid clock_gettime() clock id! "
- "Fallback to unix time.");
- }
+ CRI("Cannot get a valid clock_gettime() clock id! Fallback to unix time");
#else
# ifndef _WIN32
# if defined(__APPLE__) && defined(__MACH__)
mach_timebase_info_data_t info;
kern_return_t err = mach_timebase_info(&info);
if (err == 0)
- {
- _ecore_time_clock_conversion = 1e-9 * (double)info.numer / (double)info.denom;
- }
+   _ecore_time_clock_conversion = 1e-9 * (double)info.numer / (double)info.denom;
else
- {
- WRN("Unable to get timebase info. Fallback to nanoseconds.");
- }
+ WRN("Unable to get timebase info. Fallback to nanoseconds");
# else
-# warning "Your platform isn't supported yet"
- CRI("Platform does not support clock_gettime. "
- "Fallback to unix time.");
+# warning "Your platform isn't supported yet"
+ CRI("Platform does not support clock_gettime. Fallback to unix time");
# endif
# endif
#endif
-
- _ecore_time_loop_time = ecore_time_get();
+ ecore_loop_time_set(ecore_time_get());
}
diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c
index b2f8801459..106544558b 100644
--- a/src/lib/ecore/ecore_timer.c
+++ b/src/lib/ecore/ecore_timer.c
@@ -13,45 +13,46 @@
#define MY_CLASS EFL_LOOP_TIMER_CLASS
#define MY_CLASS_NAME "Efl_Loop_Timer"
-#define ECORE_TIMER_CHECK(obj) \
- if (!efl_isa((obj), MY_CLASS)) \
- return
+#define ECORE_TIMER_CHECK(obj) if (!efl_isa((obj), MY_CLASS)) return
+
+struct _Ecore_Timer_Legacy
+{
+ Ecore_Task_Cb func;
+
+ const void *data;
+
+ Eina_Bool inside_call : 1;
+ Eina_Bool delete_me : 1;
+};
struct _Efl_Loop_Timer_Data
{
EINA_INLIST;
Eo *object;
+ Eo *loop;
+ Efl_Loop_Data *loop_data;
- double in;
- double at;
- double pending;
+ double in;
+ double at;
+ double pending;
- int listening;
+ int listening;
- unsigned char just_added : 1;
- unsigned char frozen : 1;
- unsigned char initialized : 1;
- unsigned char noparent : 1;
+ Eina_Bool just_added : 1;
+ Eina_Bool frozen : 1;
+ Eina_Bool initialized : 1;
+ Eina_Bool noparent : 1;
+ Eina_Bool constructed : 1;
+ Eina_Bool finalized : 1;
};
-typedef struct _Efl_Loop_Timer_Data Efl_Loop_Timer_Data;
-
-static void _efl_loop_timer_util_delay(Efl_Loop_Timer_Data *timer,
- double add);
-static void _efl_loop_timer_util_instanciate(Efl_Loop_Timer_Data *timer);
-static void _efl_loop_timer_set(Efl_Loop_Timer_Data *timer,
- double at,
- double in);
-
-static Eina_Inlist *timers = NULL;
-static Eina_Inlist *suspended = NULL;
-
-static Efl_Loop_Timer_Data *timer_current = NULL;
+typedef struct _Ecore_Timer_Legacy Ecore_Timer_Legacy;
-static int timers_added = 0;
+static void _efl_loop_timer_util_delay(Efl_Loop_Timer_Data *timer, double add);
+static void _efl_loop_timer_util_instanciate(Efl_Loop_Data *loop, Efl_Loop_Timer_Data *timer);
+static void _efl_loop_timer_set(Efl_Loop_Timer_Data *timer, double at, double in);
-static double last_check = 0.0;
static double precision = 10.0 / 1000000.0;
EAPI double
@@ -65,20 +66,15 @@ EAPI void
ecore_timer_precision_set(double value)
{
EINA_MAIN_LOOP_CHECK_RETURN;
-
- if (value < 0.0)
- {
- ERR("Precision %f less than zero, ignored", value);
- return ;
- }
+ if (value < 0.0) value = 0.0;
precision = value;
}
static void
_check_timer_event_catcher_add(void *data, const Efl_Event *event)
{
- const Efl_Callback_Array_Item *array = event->info;
Efl_Loop_Timer_Data *timer = data;
+ const Efl_Callback_Array_Item *array = event->info;
int i;
for (i = 0; array[i].desc != NULL; i++)
@@ -86,7 +82,7 @@ _check_timer_event_catcher_add(void *data, const Efl_Event *event)
if (array[i].desc == EFL_LOOP_TIMER_EVENT_TICK)
{
if (timer->listening++ > 0) return;
- _efl_loop_timer_util_instanciate(timer);
+ _efl_loop_timer_util_instanciate(timer->loop_data, timer);
// No need to walk more than once per array as you can not del
// a partial array
return;
@@ -97,8 +93,8 @@ _check_timer_event_catcher_add(void *data, const Efl_Event *event)
static void
_check_timer_event_catcher_del(void *data, const Efl_Event *event)
{
- const Efl_Callback_Array_Item *array = event->info;
Efl_Loop_Timer_Data *timer = data;
+ const Efl_Callback_Array_Item *array = event->info;
int i;
for (i = 0; array[i].desc != NULL; i++)
@@ -106,7 +102,7 @@ _check_timer_event_catcher_del(void *data, const Efl_Event *event)
if (array[i].desc == EFL_LOOP_TIMER_EVENT_TICK)
{
if ((--timer->listening) > 0) return;
- _efl_loop_timer_util_instanciate(timer);
+ _efl_loop_timer_util_instanciate(timer->loop_data, timer);
return;
}
}
@@ -120,59 +116,38 @@ EOLIAN static Eo *
_efl_loop_timer_efl_object_constructor(Eo *obj, Efl_Loop_Timer_Data *timer)
{
efl_constructor(efl_super(obj, MY_CLASS));
-
efl_event_callback_array_add(obj, timer_watch(), timer);
-
efl_wref_add(obj, &timer->object);
- timer->initialized = EINA_FALSE;
timer->in = -1.0;
-
+ timer->constructed = EINA_TRUE;
return obj;
}
EOLIAN static Eo *
_efl_loop_timer_efl_object_finalize(Eo *obj, Efl_Loop_Timer_Data *pd)
{
- if (pd->at < ecore_loop_time_get())
- {
- pd->at = ecore_time_get() + pd->in;
- }
- else
- {
- pd->at += pd->in;
- }
+ if (pd->at < ecore_loop_time_get()) pd->at = ecore_time_get() + pd->in;
+ else pd->at += pd->in;
+
+ pd->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
+ pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS);
- if (pd->in < 0)
+ if (pd->in < 0.0)
{
ERR("You need to specify the interval of a timer to create a valid timer.");
return NULL;
}
-
pd->initialized = EINA_TRUE;
-
+ pd->finalized = EINA_TRUE;
_efl_loop_timer_set(pd, pd->at, pd->in);
-
return efl_finalize(efl_super(obj, MY_CLASS));
}
-typedef struct _Ecore_Timer_Legacy Ecore_Timer_Legacy;
-struct _Ecore_Timer_Legacy
-{
- Ecore_Task_Cb func;
-
- const void *data;
-
- Eina_Bool inside_call : 1;
- Eina_Bool delete_me : 1;
-};
-
static void
_ecore_timer_legacy_del(void *data, const Efl_Event *event EINA_UNUSED)
{
- Ecore_Timer_Legacy *legacy = data;
-
- free(legacy);
+ free(data);
}
static void
@@ -181,11 +156,10 @@ _ecore_timer_legacy_tick(void *data, const Efl_Event *event)
Ecore_Timer_Legacy *legacy = data;
legacy->inside_call = 1;
- if (!_ecore_call_task_cb(legacy->func, (void*)legacy->data) ||
+ if (!_ecore_call_task_cb(legacy->func, (void *)legacy->data) ||
legacy->delete_me)
efl_del(event->object);
- else
- legacy->inside_call = 0;
+ else legacy->inside_call = 0;
}
EFL_CALLBACKS_ARRAY_DEFINE(legacy_timer,
@@ -193,9 +167,7 @@ EFL_CALLBACKS_ARRAY_DEFINE(legacy_timer,
{ EFL_EVENT_DEL, _ecore_timer_legacy_del });
EAPI Ecore_Timer *
-ecore_timer_add(double in,
- Ecore_Task_Cb func,
- const void *data)
+ecore_timer_add(double in, Ecore_Task_Cb func, const void *data)
{
Ecore_Timer_Legacy *legacy;
Eo *timer;
@@ -210,14 +182,11 @@ ecore_timer_add(double in,
efl_event_callback_array_add(efl_added, legacy_timer(), legacy),
efl_key_data_set(efl_added, "_legacy", legacy),
efl_loop_timer_interval_set(efl_added, in));
-
return timer;
}
EAPI Ecore_Timer *
-ecore_timer_loop_add(double in,
- Ecore_Task_Cb func,
- const void *data)
+ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data)
{
Ecore_Timer_Legacy *legacy;
Eo *timer;
@@ -233,7 +202,6 @@ ecore_timer_loop_add(double in,
efl_key_data_set(efl_added, "_legacy", legacy),
efl_loop_timer_loop_reset(efl_added),
efl_loop_timer_interval_set(efl_added, in));
-
return timer;
}
@@ -256,41 +224,28 @@ ecore_timer_del(Ecore_Timer *timer)
return NULL;
}
- data = (void*) legacy->data;
-
- if (legacy->inside_call)
- legacy->delete_me = EINA_TRUE;
- else
- efl_del(timer);
-
+ data = (void *)legacy->data;
+ if (legacy->inside_call) legacy->delete_me = EINA_TRUE;
+ else efl_del(timer);
return data;
}
EOLIAN static void
_efl_loop_timer_interval_set(Eo *obj EINA_UNUSED, Efl_Loop_Timer_Data *timer, double in)
{
- EINA_MAIN_LOOP_CHECK_RETURN;
if (in < 0.0) in = 0.0;
-
timer->in = in;
}
EOLIAN static double
_efl_loop_timer_interval_get(Eo *obj EINA_UNUSED, Efl_Loop_Timer_Data *timer)
{
- double ret = -1.0;
-
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(ret);
- ret = timer->in;
-
- return ret;
+ return timer->in;
}
EOLIAN static void
_efl_loop_timer_delay(Eo *obj EINA_UNUSED, Efl_Loop_Timer_Data *pd, double add)
{
- EINA_MAIN_LOOP_CHECK_RETURN;
-
_efl_loop_timer_util_delay(pd, add);
}
@@ -298,23 +253,20 @@ EOLIAN static void
_efl_loop_timer_reset(Eo *obj EINA_UNUSED, Efl_Loop_Timer_Data *timer)
{
double now, add;
- EINA_MAIN_LOOP_CHECK_RETURN;
+ if (!timer->loop_data) return;
// Do not reset the current timer while inside the callback
- if (timer_current == timer) return ;
+ if (timer->loop_data->timer_current == timer) return;
now = ecore_time_get();
-
if (!timer->initialized)
{
timer->at = now;
return;
}
- if (timer->frozen)
- add = timer->pending;
- else
- add = timer->at - now;
+ if (timer->frozen) add = timer->pending;
+ else add = timer->at - now;
_efl_loop_timer_util_delay(timer, timer->in - add);
}
@@ -322,102 +274,80 @@ EOLIAN static void
_efl_loop_timer_loop_reset(Eo *obj EINA_UNUSED, Efl_Loop_Timer_Data *timer)
{
double now, add;
- EINA_MAIN_LOOP_CHECK_RETURN;
+ if (!timer->loop_data) return;
// Do not reset the current timer while inside the callback
- if (timer_current == timer) return ;
+ if (timer->loop_data->timer_current == timer) return;
now = ecore_loop_time_get();
-
if (!timer->initialized)
{
timer->at = now;
- return ;
+ return;
}
- if (timer->frozen)
- add = timer->pending;
- else
- add = timer->at - now;
+ if (timer->frozen) add = timer->pending;
+ else add = timer->at - now;
_efl_loop_timer_util_delay(timer, timer->in - add);
}
EOLIAN static double
_efl_loop_timer_pending_get(Eo *obj EINA_UNUSED, Efl_Loop_Timer_Data *timer)
{
- double now;
- double ret = 0.0;
-
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(ret);
+ double now, ret = 0.0;
now = ecore_time_get();
-
- if (timer->frozen)
- ret = timer->pending;
- else
- ret = timer->at - now;
-
+ if (timer->frozen) ret = timer->pending;
+ else ret = timer->at - now;
return ret;
}
EAPI void
ecore_timer_freeze(Ecore_Timer *timer)
{
- EINA_MAIN_LOOP_CHECK_RETURN;
ECORE_TIMER_CHECK(timer);
efl_event_freeze(timer);
}
EOLIAN static void
-_efl_loop_timer_efl_object_event_freeze(Eo *obj EINA_UNUSED, Efl_Loop_Timer_Data *timer)
+_efl_loop_timer_efl_object_event_freeze(Eo *obj, Efl_Loop_Timer_Data *timer)
{
double now;
- EINA_MAIN_LOOP_CHECK_RETURN;
-
efl_event_freeze(efl_super(obj, MY_CLASS));
-
- /* Timer already frozen */
- if (timer->frozen)
- return;
+ // Timer already frozen
+ if (timer->frozen) return;
if (EINA_UNLIKELY(!timer->initialized))
{
- ERR("Attempt freezing an non initialized timer.");
+ ERR("Attempt freezing an non unfinalized timer.");
return;
}
- now = ecore_loop_time_get();
+ now = efl_loop_time_get(timer->loop);
timer->pending = timer->at - now;
-
timer->at = 0.0;
timer->frozen = 1;
- _efl_loop_timer_util_instanciate(timer);
+ _efl_loop_timer_util_instanciate(timer->loop_data, timer);
}
EAPI Eina_Bool
ecore_timer_freeze_get(Ecore_Timer *timer)
{
- int r = 0;
-
EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
- r = efl_event_freeze_count_get(timer);
- return !!r;
+ return !!efl_event_freeze_count_get(timer);
}
EOLIAN static int
_efl_loop_timer_efl_object_event_freeze_count_get(Eo *obj EINA_UNUSED, Efl_Loop_Timer_Data *timer)
{
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
-
return timer->frozen;
}
EAPI void
ecore_timer_thaw(Ecore_Timer *timer)
{
- EINA_MAIN_LOOP_CHECK_RETURN;
ECORE_TIMER_CHECK(timer);
efl_event_thaw(timer);
}
@@ -427,17 +357,16 @@ _efl_loop_timer_efl_object_event_thaw(Eo *obj, Efl_Loop_Timer_Data *timer)
{
double now;
- EINA_MAIN_LOOP_CHECK_RETURN;
-
efl_event_thaw(efl_super(obj, MY_CLASS));
- /* Timer not frozen */
- if (!timer->frozen)
- return ;
+ if (!timer->frozen) return; // Timer not frozen
- suspended = eina_inlist_remove(suspended, EINA_INLIST_GET(timer));
+ if (timer->loop_data)
+ {
+ timer->loop_data->suspended = eina_inlist_remove
+ (timer->loop_data->suspended, EINA_INLIST_GET(timer));
+ }
now = ecore_time_get();
-
_efl_loop_timer_set(timer, timer->pending + now, timer->in);
}
@@ -448,139 +377,130 @@ ecore_timer_dump(void)
}
static void
-_efl_loop_timer_util_instanciate(Efl_Loop_Timer_Data *timer)
+_efl_loop_timer_util_loop_clear(Efl_Loop_Timer_Data *pd)
{
- Efl_Loop_Timer_Data *t2;
Eina_Inlist *first;
+ if (!pd->loop_data) return;
+ // Check if we are the current timer, if so move along
+ if (pd->loop_data->timer_current == pd)
+ pd->loop_data->timer_current = (Efl_Loop_Timer_Data *)
+ EINA_INLIST_GET(pd)->next;
+
// Remove the timer from all possible pending list
- first = eina_inlist_first(EINA_INLIST_GET(timer));
- if (first == timers)
- timers = eina_inlist_remove(timers, EINA_INLIST_GET(timer));
- else if (first == suspended)
- suspended = eina_inlist_remove(suspended, EINA_INLIST_GET(timer));
+ first = eina_inlist_first(EINA_INLIST_GET(pd));
+ if (first == pd->loop_data->timers)
+ pd->loop_data->timers = eina_inlist_remove
+ (pd->loop_data->timers, EINA_INLIST_GET(pd));
+ else if (first == pd->loop_data->suspended)
+ pd->loop_data->suspended = eina_inlist_remove
+ (pd->loop_data->suspended, EINA_INLIST_GET(pd));
+}
+
+static void
+_efl_loop_timer_util_instanciate(Efl_Loop_Data *loop, Efl_Loop_Timer_Data *timer)
+{
+ Efl_Loop_Timer_Data *t2;
+
+ if (!loop) return;
+ _efl_loop_timer_util_loop_clear(timer);
// And start putting it back where it belong
- if (!timer->listening || timer->frozen || timer->at <= 0.0 || timer->in < 0.0)
+ if ((!timer->listening) || (timer->frozen) ||
+ (timer->at <= 0.0) || (timer->in < 0.0))
{
- suspended = eina_inlist_prepend(suspended, EINA_INLIST_GET(timer));
- return ;
+ loop->suspended = eina_inlist_prepend(loop->suspended,
+ EINA_INLIST_GET(timer));
+ return;
}
if (!timer->initialized)
{
ERR("Trying to instantiate an uninitialized timer is impossible.");
- return ;
+ return;
}
- EINA_INLIST_REVERSE_FOREACH(timers, t2)
+ EINA_INLIST_REVERSE_FOREACH(loop->timers, t2)
{
if (timer->at > t2->at)
{
- timers = eina_inlist_append_relative(timers,
- EINA_INLIST_GET(timer),
- EINA_INLIST_GET(t2));
+ loop->timers = eina_inlist_append_relative(loop->timers,
+ EINA_INLIST_GET(timer),
+ EINA_INLIST_GET(t2));
return;
}
}
- timers = eina_inlist_prepend(timers, EINA_INLIST_GET(timer));
+ loop->timers = eina_inlist_prepend(loop->timers, EINA_INLIST_GET(timer));
}
static void
-_efl_loop_timer_util_delay(Efl_Loop_Timer_Data *timer,
- double add)
+_efl_loop_timer_util_delay(Efl_Loop_Timer_Data *timer, double add)
{
if (!timer->initialized)
{
ERR("Impossible to delay an uninitialized timer.");
- return ;
+ return;
}
-
if (timer->frozen)
{
timer->pending += add;
- return ;
+ return;
}
-
_efl_loop_timer_set(timer, timer->at + add, timer->in);
}
EOLIAN static void
-_efl_loop_timer_efl_object_parent_set(Eo *obj EINA_UNUSED, Efl_Loop_Timer_Data *pd, Efl_Object *parent)
+_efl_loop_timer_efl_object_parent_set(Eo *obj, Efl_Loop_Timer_Data *pd, Efl_Object *parent)
{
- Eina_Inlist *first;
-
- first = eina_inlist_first(EINA_INLIST_GET(pd));
- if (first == timers)
- timers = eina_inlist_remove(timers, EINA_INLIST_GET(pd));
- else if (first == suspended)
- suspended = eina_inlist_remove(suspended, EINA_INLIST_GET(pd));
-
efl_parent_set(efl_super(obj, EFL_LOOP_TIMER_CLASS), parent);
- if (efl_parent_get(obj) != parent)
- return ;
+ if ((!pd->constructed) || (!pd->finalized)) return;
- if (parent != NULL)
- {
- _efl_loop_timer_util_instanciate(pd);
- pd->noparent = EINA_FALSE;
- }
- else
- {
- pd->noparent = EINA_TRUE;
- }
-}
+ _efl_loop_timer_util_loop_clear(pd);
-EOLIAN static void
-_efl_loop_timer_efl_object_destructor(Eo *obj, Efl_Loop_Timer_Data *pd)
-{
- Eina_Inlist *first;
+ pd->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
+ pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS);
- // Check if we are the current timer, if so move along
- if (timer_current == pd)
- timer_current = (Efl_Loop_Timer_Data *)EINA_INLIST_GET(pd)->next;
+ if (efl_parent_get(obj) != parent) return;
- // Remove the timer from all possible pending list
- first = eina_inlist_first(EINA_INLIST_GET(pd));
- if (first == timers)
- timers = eina_inlist_remove(timers, EINA_INLIST_GET(pd));
- else if (first == suspended)
- suspended = eina_inlist_remove(suspended, EINA_INLIST_GET(pd));
+ _efl_loop_timer_util_instanciate(pd->loop_data, pd);
- efl_destructor(efl_super(obj, MY_CLASS));
+ if (parent != NULL) pd->noparent = EINA_FALSE;
+ else pd->noparent = EINA_TRUE;
}
-void
-_efl_loop_timer_shutdown(void)
+EOLIAN static void
+_efl_loop_timer_efl_object_destructor(Eo *obj, Efl_Loop_Timer_Data *pd)
{
- timer_current = NULL;
+ _efl_loop_timer_util_loop_clear(pd);
+ efl_destructor(efl_super(obj, MY_CLASS));
}
void
-_efl_loop_timer_enable_new(void)
+_efl_loop_timer_enable_new(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
{
Efl_Loop_Timer_Data *timer;
- if (!timers_added) return;
- timers_added = 0;
- EINA_INLIST_FOREACH(timers, timer) timer->just_added = 0;
+ if (!pd->timers_added) return;
+ pd->timers_added = 0;
+ EINA_INLIST_FOREACH(pd->timers, timer) timer->just_added = 0;
}
int
-_efl_loop_timers_exists(void)
+_efl_loop_timers_exists(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
{
- return !!timers;
+ return !!pd->timers;
}
static inline Ecore_Timer *
-_efl_loop_timer_first_get(void)
+_efl_loop_timer_first_get(Eo *ob EINA_UNUSED, Efl_Loop_Data *pd)
{
Efl_Loop_Timer_Data *timer;
- EINA_INLIST_FOREACH(timers, timer)
- if (!timer->just_added) return timer->object;
-
+ EINA_INLIST_FOREACH(pd->timers, timer)
+ {
+ if (!timer->just_added) return timer->object;
+ }
return NULL;
}
@@ -595,41 +515,40 @@ _efl_loop_timer_after_get(Efl_Loop_Timer_Data *base)
{
if (EINA_UNLIKELY(!timer->initialized)) continue; // This shouldn't happen
if (timer->at >= maxtime) break;
- if (!timer->just_added)
- valid_timer = timer;
+ if (!timer->just_added) valid_timer = timer;
}
-
return valid_timer;
}
double
-_efl_loop_timer_next_get(void)
+_efl_loop_timer_next_get(Eo *obj, Efl_Loop_Data *pd)
{
Ecore_Timer *object;
Efl_Loop_Timer_Data *first;
double now;
double in;
- object = _efl_loop_timer_first_get();
+ object = _efl_loop_timer_first_get(obj, pd);
if (!object) return -1;
first = _efl_loop_timer_after_get(efl_data_scope_get(object, MY_CLASS));
-
now = ecore_loop_time_get();
in = first->at - now;
if (in < 0) in = 0;
-
return in;
}
static inline void
-_efl_loop_timer_reschedule(Efl_Loop_Timer_Data *timer,
- double when)
+_efl_loop_timer_reschedule(Efl_Loop_Timer_Data *timer, double when)
{
if (timer->frozen) return;
- if (timers && !timer->noparent)
- timers = eina_inlist_remove(timers, EINA_INLIST_GET(timer));
+ if (timer->loop_data)
+ {
+ if (timer->loop_data->timers && (!timer->noparent))
+ timer->loop_data->timers = eina_inlist_remove
+ (timer->loop_data->timers, EINA_INLIST_GET(timer));
+ }
/* if the timer would have gone off more than 15 seconds ago,
* assume that the system hung and set the timer to go off
@@ -647,51 +566,51 @@ _efl_loop_timer_reschedule(Efl_Loop_Timer_Data *timer,
}
void
-_efl_loop_timer_expired_timers_call(double when)
+_efl_loop_timer_expired_timers_call(Eo *obj, Efl_Loop_Data *pd, double when)
{
- /* call the first expired timer until no expired timers exist */
- while (_efl_loop_timer_expired_call(when)) ;
+ // call the first expired timer until no expired timers exist
+ while (_efl_loop_timer_expired_call(obj, pd, when));
}
int
-_efl_loop_timer_expired_call(double when)
+_efl_loop_timer_expired_call(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, double when)
{
- if (!timers) return 0;
- if (last_check > when)
+ if (!pd->timers) return 0;
+ if (pd->last_check > when)
{
Efl_Loop_Timer_Data *timer;
- /* User set time backwards */
- EINA_INLIST_FOREACH(timers, timer) timer->at -= (last_check - when);
+ // User set time backwards
+ EINA_INLIST_FOREACH(pd->timers, timer)
+ timer->at -= (pd->last_check - when);
}
- last_check = when;
+ pd->last_check = when;
- if (!timer_current)
- {
- /* regular main loop, start from head */
- timer_current = (Efl_Loop_Timer_Data *)timers;
- }
+ if (!pd->timer_current) // regular main loop, start from head
+ pd->timer_current = (Efl_Loop_Timer_Data *)pd->timers;
else
{
- /* recursive main loop, continue from where we were */
- Efl_Loop_Timer_Data *timer_old = timer_current;
+ // recursive main loop, continue from where we were
+ Efl_Loop_Timer_Data *timer_old = pd->timer_current;
- timer_current = (Efl_Loop_Timer_Data *)EINA_INLIST_GET(timer_current)->next;
+ pd->timer_current = (Efl_Loop_Timer_Data *)
+ EINA_INLIST_GET(pd->timer_current)->next;
_efl_loop_timer_reschedule(timer_old, when);
}
- while (timer_current)
+ while (pd->timer_current)
{
- Efl_Loop_Timer_Data *timer = timer_current;
+ Efl_Loop_Timer_Data *timer = pd->timer_current;
if (timer->at > when)
{
- timer_current = NULL; /* ended walk, next should restart. */
+ pd->timer_current = NULL; // ended walk, next should restart.
return 0;
}
if (timer->just_added)
{
- timer_current = (Efl_Loop_Timer_Data *)EINA_INLIST_GET(timer_current)->next;
+ pd->timer_current = (Efl_Loop_Timer_Data *)
+ EINA_INLIST_GET(pd->timer_current)->next;
continue;
}
@@ -700,11 +619,11 @@ _efl_loop_timer_expired_call(double when)
efl_event_callback_call(timer->object, EFL_LOOP_TIMER_EVENT_TICK, NULL);
eina_evlog("-timer", timer, 0.0, NULL);
- /* may have changed in recursive main loops */
- /* this current timer can not die yet as we hold a reference on it */
- if (timer_current)
- timer_current = (Efl_Loop_Timer_Data *)EINA_INLIST_GET(timer_current)->next;
-
+ // may have changed in recursive main loops
+ // this current timer can not die yet as we hold a reference on it
+ if (pd->timer_current)
+ pd->timer_current = (Efl_Loop_Timer_Data *)
+ EINA_INLIST_GET(pd->timer_current)->next;
_efl_loop_timer_reschedule(timer, when);
efl_unref(timer->object);
}
@@ -712,19 +631,17 @@ _efl_loop_timer_expired_call(double when)
}
static void
-_efl_loop_timer_set(Efl_Loop_Timer_Data *timer,
- double at,
- double in)
+_efl_loop_timer_set(Efl_Loop_Timer_Data *timer, double at, double in)
{
- timers_added = 1;
+ if (!timer->loop_data) return;
+ timer->loop_data->timers_added = 1;
timer->at = at;
timer->in = in;
timer->just_added = 1;
timer->initialized = 1;
timer->frozen = 0;
timer->pending = 0.0;
-
- _efl_loop_timer_util_instanciate(timer);
+ _efl_loop_timer_util_instanciate(timer->loop_data, timer);
}
#include "efl_loop_timer.eo.c"
diff --git a/src/lib/ecore/efl_loop.c b/src/lib/ecore/efl_loop.c
new file mode 100644
index 0000000000..661bf654a9
--- /dev/null
+++ b/src/lib/ecore/efl_loop.c
@@ -0,0 +1,717 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#include "ecore_main_common.h"
+
+typedef struct _Efl_Loop_Promise_Simple_Data Efl_Loop_Promise_Simple_Data;
+typedef struct _Efl_Internal_Promise Efl_Internal_Promise;
+
+struct _Efl_Loop_Promise_Simple_Data
+{
+ union {
+ Ecore_Timer *timer;
+ Ecore_Idler *idler;
+ };
+ Eina_Promise *promise;
+};
+GENERIC_ALLOC_SIZE_DECLARE(Efl_Loop_Promise_Simple_Data);
+
+EOLIAN static Efl_Loop_Message_Handler *
+_efl_loop_message_handler_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Loop *loop, const Efl_Class *klass)
+{
+ Message_Handler mh = { 0 }, *mh2;
+ Efl_Loop_Data *ld = efl_data_scope_get(loop, EFL_LOOP_CLASS);
+ unsigned int i, n;
+
+ if (!ld) return NULL;
+ n = eina_inarray_count(ld->message_handlers);
+ for (i = 0; i < n; i++)
+ {
+ mh2 = eina_inarray_nth(ld->message_handlers, i);
+ if (mh2->klass == klass) return mh2->handler;
+ }
+ mh.klass = klass;
+ mh.handler = efl_add(klass, loop);
+ eina_inarray_push(ld->message_handlers, &mh);
+ return mh.handler;
+}
+
+Efl_Version _app_efl_version = { 0, 0, 0, 0, NULL, NULL };
+
+Eo *_mainloop_singleton = NULL;
+Efl_Loop_Data *_mainloop_singleton_data = NULL;
+
+static void
+_mainloop_singleton_cb_del(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
+{
+ _mainloop_singleton = NULL;
+ _mainloop_singleton_data = NULL;
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(_mainloop_singleton_callbacks,
+ { EFL_EVENT_DEL, _mainloop_singleton_cb_del });
+
+EOLIAN static Efl_Loop *
+_efl_loop_main_get(Efl_Class *klass EINA_UNUSED, void *_pd EINA_UNUSED)
+{
+ if (_mainloop_singleton) return _mainloop_singleton;
+ _mainloop_singleton = efl_add(EFL_LOOP_CLASS, NULL);
+ _mainloop_singleton_data = efl_data_scope_get(_mainloop_singleton,
+ EFL_LOOP_CLASS);
+ efl_event_callback_array_add(_mainloop_singleton,
+ _mainloop_singleton_callbacks(), NULL);
+ return _mainloop_singleton;
+}
+
+EAPI Eo *
+ecore_main_loop_get(void)
+{
+ return efl_loop_main_get(EFL_LOOP_CLASS);
+}
+
+EOLIAN static void
+_efl_loop_iterate(Eo *obj, Efl_Loop_Data *pd)
+{
+ _ecore_main_loop_iterate(obj, pd);
+}
+
+EOLIAN static int
+_efl_loop_iterate_may_block(Eo *obj, Efl_Loop_Data *pd, int may_block)
+{
+ return _ecore_main_loop_iterate_may_block(obj, pd, may_block);
+}
+
+// FIXME: This should return an Eina_Value, but that doesn't work at the moment
+EOLIAN static Eina_Value *
+_efl_loop_begin(Eo *obj, Efl_Loop_Data *pd)
+{
+ _ecore_main_loop_begin(obj, pd);
+ return &(pd->exit_code);
+}
+
+EOLIAN static void
+_efl_loop_quit(Eo *obj, Efl_Loop_Data *pd, Eina_Value exit_code)
+{
+ _ecore_main_loop_quit(obj, pd);
+ pd->exit_code = exit_code;
+}
+
+EOLIAN static void
+_efl_loop_time_set(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, double t)
+{
+ pd->loop_time = t;
+}
+
+EOLIAN static double
+_efl_loop_time_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
+{
+ return pd->loop_time;
+}
+
+EAPI void
+efl_exit(int exit_code)
+{
+ Eina_Value v = EINA_VALUE_EMPTY;
+
+ eina_value_setup(&v, EINA_VALUE_TYPE_INT);
+ eina_value_set(&v, &exit_code);
+ efl_loop_quit(ecore_main_loop_get(), v);
+}
+
+EOLIAN static Efl_Object *
+_efl_loop_efl_object_provider_find(Eo *obj, Efl_Loop_Data *pd, const Efl_Object *klass)
+{
+ Efl_Object *r;
+
+ if (klass == EFL_LOOP_CLASS) return obj;
+
+ r = eina_hash_find(pd->providers, &klass);
+ if (r) return r;
+
+ return efl_provider_find(efl_super(obj, EFL_LOOP_CLASS), klass);
+}
+
+EAPI int
+efl_loop_exit_code_process(Eina_Value *value)
+{
+ const Eina_Value_Type *t = eina_value_type_get(value);
+ int r = 0;
+
+ if (t == EINA_VALUE_TYPE_UCHAR ||
+ t == EINA_VALUE_TYPE_USHORT ||
+ t == EINA_VALUE_TYPE_UINT ||
+ t == EINA_VALUE_TYPE_ULONG ||
+ t == EINA_VALUE_TYPE_UINT64 ||
+ t == EINA_VALUE_TYPE_CHAR ||
+ t == EINA_VALUE_TYPE_SHORT ||
+ t == EINA_VALUE_TYPE_INT ||
+ t == EINA_VALUE_TYPE_LONG ||
+ t == EINA_VALUE_TYPE_INT64 ||
+ t == EINA_VALUE_TYPE_FLOAT ||
+ t == EINA_VALUE_TYPE_DOUBLE)
+ {
+ Eina_Value v = EINA_VALUE_EMPTY;
+
+ eina_value_setup(&v, EINA_VALUE_TYPE_INT);
+ if (!eina_value_convert(&v, value)) r = -1;
+ else eina_value_get(&v, &v);
+ }
+ else
+ {
+ FILE *out = stdout;
+ char *msg;
+
+ msg = eina_value_to_string(value);
+
+ if (t == EINA_VALUE_TYPE_ERROR)
+ {
+ r = -1;
+ out = stderr;
+ }
+ fprintf(out, "%s\n", msg);
+ }
+ return r;
+}
+
+static void
+_poll_trigger(void *data, const Efl_Event *event)
+{
+ Eo *parent = efl_parent_get(event->object);
+
+ efl_event_callback_call(parent, data, NULL);
+}
+
+static void
+_check_event_catcher_add(void *data, const Efl_Event *event)
+{
+ const Efl_Callback_Array_Item *array = event->info;
+ Efl_Loop_Data *pd = data;
+ int i;
+
+ for (i = 0; array[i].desc != NULL; i++)
+ {
+ if (array[i].desc == EFL_LOOP_EVENT_IDLE)
+ {
+ ++pd->idlers;
+ }
+ // XXX: all the below are kind of bad. ecore_pollers were special.
+ // they all woke up at the SAME time based on interval, (all pollers
+ // of interval 1 woke up together, those with 2 woke up when 1 and
+ // 2 woke up, 4 woke up together along with 1 and 2 etc.
+ // the below means they will just go off whenever but at a pre
+ // defined interval - 1/60th, 6 and 66 seconds. not really great
+ // pollers probably should be less frequent that 1/60th even on poll
+ // high, medium probably down to 1-2 sec and low - yes maybe 30 or 60
+ // sec... still - not timed to wake up together. :(
+ else if (array[i].desc == EFL_LOOP_EVENT_POLL_HIGH)
+ {
+ if (!pd->poll_high)
+ {
+ // Would be better to have it in sync with normal wake up
+ // of the main loop for better energy efficiency, I guess.
+ pd->poll_high = efl_add
+ (EFL_LOOP_TIMER_CLASS, event->object,
+ efl_event_callback_add(efl_added,
+ EFL_LOOP_TIMER_EVENT_TICK,
+ _poll_trigger,
+ EFL_LOOP_EVENT_POLL_HIGH),
+ efl_loop_timer_interval_set(efl_added, 1.0 / 60.0));
+ }
+ ++pd->pollers.high;
+ }
+ else if (array[i].desc == EFL_LOOP_EVENT_POLL_MEDIUM)
+ {
+ if (!pd->poll_medium)
+ {
+ pd->poll_medium = efl_add
+ (EFL_LOOP_TIMER_CLASS, event->object,
+ efl_event_callback_add(efl_added,
+ EFL_LOOP_TIMER_EVENT_TICK,
+ _poll_trigger,
+ EFL_LOOP_EVENT_POLL_MEDIUM),
+ efl_loop_timer_interval_set(efl_added, 6));
+ }
+ ++pd->pollers.medium;
+ }
+ else if (array[i].desc == EFL_LOOP_EVENT_POLL_LOW)
+ {
+ if (!pd->poll_low)
+ {
+ pd->poll_low = efl_add
+ (EFL_LOOP_TIMER_CLASS, event->object,
+ efl_event_callback_add(efl_added,
+ EFL_LOOP_TIMER_EVENT_TICK,
+ _poll_trigger,
+ EFL_LOOP_EVENT_POLL_LOW),
+ efl_loop_timer_interval_set(efl_added, 66));
+ }
+ ++pd->pollers.low;
+ }
+ }
+}
+
+static void
+_check_event_catcher_del(void *data, const Efl_Event *event)
+{
+ const Efl_Callback_Array_Item *array = event->info;
+ Efl_Loop_Data *pd = data;
+ int i;
+
+ for (i = 0; array[i].desc != NULL; i++)
+ {
+ if (array[i].desc == EFL_LOOP_EVENT_IDLE)
+ {
+ --pd->idlers;
+ }
+ else if (array[i].desc == EFL_LOOP_EVENT_POLL_HIGH)
+ {
+ --pd->pollers.high;
+ if (!pd->pollers.high)
+ {
+ ecore_timer_del(pd->poll_high);
+ pd->poll_high = NULL;
+ }
+ }
+ else if (array[i].desc == EFL_LOOP_EVENT_POLL_MEDIUM)
+ {
+ --pd->pollers.medium;
+ if (!pd->pollers.medium)
+ {
+ ecore_timer_del(pd->poll_medium);
+ pd->poll_medium = NULL;
+ }
+ }
+ else if (array[i].desc == EFL_LOOP_EVENT_POLL_LOW)
+ {
+ --pd->pollers.low;
+ if (!pd->pollers.low)
+ {
+ ecore_timer_del(pd->poll_low);
+ pd->poll_low = NULL;
+ }
+ }
+ }
+}
+
+EFL_CALLBACKS_ARRAY_DEFINE(event_catcher_watch,
+ { EFL_EVENT_CALLBACK_ADD, _check_event_catcher_add },
+ { EFL_EVENT_CALLBACK_DEL, _check_event_catcher_del });
+
+EOLIAN static Efl_Object *
+_efl_loop_efl_object_constructor(Eo *obj, Efl_Loop_Data *pd)
+{
+ obj = efl_constructor(efl_super(obj, EFL_LOOP_CLASS));
+ if (!obj) return NULL;
+
+ efl_event_callback_array_add(obj, event_catcher_watch(), pd);
+
+ pd->loop_time = ecore_time_get();
+ pd->providers = eina_hash_pointer_new(EINA_FREE_CB(efl_unref));
+ pd->message_handlers = eina_inarray_new(sizeof(Message_Handler), 32);
+#ifdef HAVE_EPOLL
+ pd->epoll_fd = -1;
+#endif
+#ifdef USE_G_MAIN_LOOP
+ pd->timer_fd = -1;
+#endif
+ return obj;
+}
+
+EOLIAN static void
+_efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
+{
+ _ecore_main_content_clear(pd);
+
+ eina_hash_free(pd->providers);
+ pd->providers = NULL;
+
+ efl_del(pd->poll_low);
+ pd->poll_low = NULL;
+ efl_del(pd->poll_medium);
+ pd->poll_medium = NULL;
+ efl_del(pd->poll_high);
+ pd->poll_high = NULL;
+
+ eina_inarray_free(pd->message_handlers);
+ pd->message_handlers = NULL;
+
+ efl_destructor(efl_super(obj, EFL_LOOP_CLASS));
+}
+
+static void
+_efl_loop_arguments_cleanup(Eina_Array *arga)
+{
+ Eina_Stringshare *s;
+
+ while ((s = eina_array_pop(arga))) eina_stringshare_del(s);
+ eina_array_free(arga);
+}
+
+static void
+_efl_loop_arguments_send(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ static Eina_Bool initialization = EINA_TRUE;
+ Efl_Loop_Arguments arge;
+ Eina_Array *arga = data;
+
+ arge.argv = arga;
+ arge.initialization = initialization;
+ initialization = EINA_FALSE;
+
+ efl_event_callback_call(ecore_main_loop_get(),
+ EFL_LOOP_EVENT_ARGUMENTS, &arge);
+
+ _efl_loop_arguments_cleanup(arga);
+}
+
+static void
+_efl_loop_arguments_cancel(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+ _efl_loop_arguments_cleanup(data);
+}
+
+// It doesn't make sense to send those argument to any other mainloop
+// As it also doesn't make sense to allow anyone to override this, so
+// should be internal for sure, not even protected.
+EAPI void
+ecore_loop_arguments_send(int argc, const char **argv)
+{
+ Eina_Future *job;
+ Eina_Array *arga;
+ int i = 0;
+
+ arga = eina_array_new(argc);
+ for (i = 0; i < argc; i++)
+ eina_array_push(arga, eina_stringshare_add(argv[i]));
+
+ job = eina_future_then(efl_loop_job(ecore_main_loop_get()),
+ _efl_loop_arguments_send, arga);
+ efl_future_Eina_FutureXXX_then(ecore_main_loop_get(), job);
+}
+
+// Only one main loop handle for now
+void
+ecore_loop_future_register(Efl_Loop *l, Efl_Future *f)
+{
+ Efl_Loop_Data *pd;
+
+ if (l == ML_OBJ) pd = ML_DAT;
+ else pd = efl_data_scope_get(l, EFL_LOOP_CLASS);
+ if (!pd) return;
+
+ pd->pending_futures = eina_list_append(pd->pending_futures, f);
+}
+
+void
+ecore_loop_future_unregister(Efl_Loop *l, Efl_Future *f)
+{
+ Efl_Loop_Data *pd;
+
+ if (l == ML_OBJ) pd = ML_DAT;
+ else pd = efl_data_scope_get(l, EFL_LOOP_CLASS);
+ if (!pd) return;
+
+ pd->pending_futures = eina_list_remove(pd->pending_futures, f);
+}
+
+void
+ecore_loop_promise_register(Efl_Loop *l, Efl_Promise *p)
+{
+ Efl_Loop_Data *pd;
+
+ if (l == ML_OBJ) pd = ML_DAT;
+ else pd = efl_data_scope_get(l, EFL_LOOP_CLASS);
+ if (!pd) return;
+
+ pd->pending_promises = eina_list_append(pd->pending_promises, p);
+}
+
+void
+ecore_loop_promise_unregister(Efl_Loop *l, Efl_Promise *p)
+{
+ Efl_Loop_Data *pd;
+
+ if (l == ML_OBJ) pd = ML_DAT;
+ else pd = efl_data_scope_get(l, EFL_LOOP_CLASS);
+ if (!pd) return;
+
+ pd->pending_promises = eina_list_remove(pd->pending_promises, p);
+}
+
+static Eina_Future *
+_efl_loop_job(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
+{
+ // 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));
+}
+
+EOLIAN static void
+_efl_loop_throttle_set(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, double amount)
+{
+ pd->throttle = ((double)amount) * 1000000.0;
+}
+
+EOLIAN static double
+_efl_loop_throttle_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
+{
+ return (double)(pd->throttle) / 1000000.0;
+}
+
+static void
+_efl_loop_idle_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
+{
+ Efl_Loop_Promise_Simple_Data *d = data;
+ ecore_idler_del(d->idler);
+ efl_loop_promise_simple_data_mp_free(d);
+}
+
+static Eina_Bool
+_efl_loop_idle_done(void *data)
+{
+ Efl_Loop_Promise_Simple_Data *d = data;
+ eina_promise_resolve(d->promise, EINA_VALUE_EMPTY);
+ efl_loop_promise_simple_data_mp_free(d);
+ return EINA_FALSE;
+}
+
+static Eina_Future *
+_efl_loop_idle(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
+{
+ Efl_Loop_Promise_Simple_Data *d;
+ Eina_Promise *p;
+
+ d = efl_loop_promise_simple_data_calloc(1);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
+
+ 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);
+ // d is dead if p is NULL
+ EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
+ d->promise = p;
+
+ // NOTE: Eolian should do efl_future_then() to bind future to object.
+ return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));
+
+idler_error:
+ efl_loop_promise_simple_data_mp_free(d);
+ return NULL;
+}
+
+static void
+_efl_loop_timeout_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
+{
+ Efl_Loop_Promise_Simple_Data *d = data;
+ ecore_timer_del(d->timer);
+ efl_loop_promise_simple_data_mp_free(d);
+}
+
+static Eina_Bool
+_efl_loop_timeout_done(void *data)
+{
+ Efl_Loop_Promise_Simple_Data *d = data;
+ eina_promise_resolve(d->promise, EINA_VALUE_EMPTY);
+ efl_loop_promise_simple_data_mp_free(d);
+ return EINA_FALSE;
+}
+
+static Eina_Future *
+_efl_loop_timeout(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, double time)
+{
+ Efl_Loop_Promise_Simple_Data *d;
+ Eina_Promise *p;
+
+ d = efl_loop_promise_simple_data_calloc(1);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
+
+ d->timer = ecore_timer_add(time, _efl_loop_timeout_done, 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);
+ // d is dead if p is NULL
+ EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
+ d->promise = p;
+
+ // NOTE: Eolian should do efl_future_then() to bind future to object.
+ return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));
+
+timer_error:
+ efl_loop_promise_simple_data_mp_free(d);
+ return NULL;
+}
+
+static Eina_Bool
+_efl_loop_register(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, const Efl_Class *klass, const Efl_Object *provider)
+{
+ // The passed object does not provide that said class.
+ if (!efl_isa(provider, klass)) return EINA_FALSE;
+
+ // Note: I would prefer to use efl_xref here, but I can't figure a nice way to
+ // call efl_xunref on hash destruction.
+ return eina_hash_add(pd->providers, &klass, efl_ref(provider));
+}
+
+static Eina_Bool
+_efl_loop_unregister(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, const Efl_Class *klass, const Efl_Object *provider)
+{
+ return eina_hash_del(pd->providers, &klass, provider);
+}
+
+void
+_efl_loop_messages_filter(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, void *handler_pd)
+{
+ Message *msg;
+
+ pd->message_walking++;
+ EINA_INLIST_FOREACH(pd->message_queue, msg)
+ {
+ if ((msg->handler) && (msg->message) && (!msg->delete_me))
+ {
+ if (!_ecore_event_do_filter(handler_pd,
+ msg->handler, msg->message))
+ {
+ efl_del(msg->message);
+ msg->handler = NULL;
+ msg->message = NULL;
+ msg->delete_me = EINA_TRUE;
+ }
+ }
+ }
+ pd->message_walking--;
+}
+
+void
+_efl_loop_messages_call(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, void *func, void *data)
+{
+ Message *msg;
+
+ pd->message_walking++;
+ EINA_INLIST_FOREACH(pd->message_queue, msg)
+ {
+ if ((msg->handler) && (msg->message) && (!msg->delete_me))
+ {
+ Eina_Bool (*fn) (void *data, void *handler, void *msg);
+
+ fn = func;
+ if (!fn(data, msg->handler, msg->message))
+ {
+ efl_del(msg->message);
+ msg->handler = NULL;
+ msg->message = NULL;
+ msg->delete_me = EINA_TRUE;
+ }
+ }
+ }
+ pd->message_walking--;
+}
+
+EOLIAN static Eina_Bool
+_efl_loop_message_process(Eo *obj, Efl_Loop_Data *pd)
+{
+ if (!pd->message_queue) return EINA_FALSE;
+ pd->message_walking++;
+ _ecore_event_filters_call(obj, pd);
+ while (pd->message_queue)
+ {
+ Message *msg = (Message *)pd->message_queue;
+ if (!msg->delete_me)
+ efl_loop_message_handler_message_call(msg->handler, msg->message);
+ else
+ {
+ if (msg->message) efl_del(msg->message);
+ pd->message_queue =
+ eina_inlist_remove(pd->message_queue,
+ pd->message_queue);
+ free(msg);
+ }
+ }
+ pd->message_walking--;
+ if (pd->message_walking == 0)
+ {
+ Message *msg;
+
+ EINA_INLIST_FREE(pd->message_queue, msg)
+ {
+ if (msg->message)
+ {
+ if (!msg->delete_me)
+ ERR("Found unprocessed event msg=%p handler=%p on queue",
+ msg->message, msg->handler);
+ efl_del(msg->message);
+ }
+ else free(msg);
+ }
+ }
+ return EINA_TRUE;
+}
+
+EOLIAN static Eina_Bool
+_efl_loop_message_exists(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
+{
+ if (pd->message_queue) return EINA_TRUE;
+ return EINA_FALSE;
+}
+
+EWAPI void
+efl_build_version_set(int vmaj, int vmin, int vmic, int revision,
+ const char *flavor, const char *build_id)
+{
+ // note: EFL has not been initialized yet at this point (ie. no eina call)
+ _app_efl_version.major = vmaj;
+ _app_efl_version.minor = vmin;
+ _app_efl_version.micro = vmic;
+ _app_efl_version.revision = revision;
+ free((char *)_app_efl_version.flavor);
+ free((char *)_app_efl_version.build_id);
+ _app_efl_version.flavor = flavor ? strdup(flavor) : NULL;
+ _app_efl_version.build_id = build_id ? strdup(build_id) : NULL;
+}
+
+EOLIAN static const Efl_Version *
+_efl_loop_app_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
+{
+ return &_app_efl_version;
+}
+
+EOLIAN static const Efl_Version *
+_efl_loop_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
+{
+ /* vanilla EFL: flavor = NULL */
+ static const Efl_Version version = {
+ .major = VMAJ,
+ .minor = VMIN,
+ .micro = VMIC,
+ .revision = VREV,
+ .build_id = EFL_BUILD_ID,
+ .flavor = NULL
+ };
+ return &version;
+}
+
+EAPI Eina_Future_Scheduler *
+efl_loop_future_scheduler_get(Eo *obj)
+{
+ if (!obj) return NULL;
+
+ if (efl_isa(obj, EFL_LOOP_CLASS))
+ return _ecore_event_future_scheduler_get();
+
+ return efl_loop_future_scheduler_get(efl_loop_get(obj));
+}
+
+#include "efl_loop.eo.c"
diff --git a/src/lib/ecore/efl_loop.eo b/src/lib/ecore/efl_loop.eo
index b806de0bb5..2162039113 100644
--- a/src/lib/ecore/efl_loop.eo
+++ b/src/lib/ecore/efl_loop.eo
@@ -77,7 +77,24 @@ class Efl.Loop (Efl.Object)
This has higher priority, for low priority use
@.idle
]]
- return: ptr(Eina.Future) @owned /* TODO: future<void> */; [[The future handle.]]
+ return: ptr(Eina.Future) @owned /* TODO: future<void> */; [[The future handle.]]
+ }
+ @property throttle {
+ [[Slow down the loop execution by forcing a sleep for a small
+ period of time every time the loop iterates/loops.]]
+ set {}
+ get {}
+ values {
+ amount : double; [[Time to sleep for each "loop iteration"]]
+ }
+ }
+ @property time {
+ [[The time point when the loop was logically woken up.]]
+ set {}
+ get {}
+ values {
+ timepoint: double; [[Time in seconds since process specfic start point]]
+ }
}
idle {
[[A future promise that will be resolved from a clean main
@@ -85,7 +102,7 @@ class Efl.Loop (Efl.Object)
This is a low priority version of @.job
]]
- return: ptr(Eina.Future) @owned /* TODO: future<void> */; [[The future handle.]]
+ return: ptr(Eina.Future) @owned /* TODO: future<void> */; [[The future handle.]]
}
timeout {
[[A future promise that will be resolved from a clean main
@@ -111,6 +128,22 @@ class Efl.Loop (Efl.Object)
}
return: bool; [[$true if successfully unregistered, $false otherwise.]]
}
+ message_handler_get @class {
+ [[ ]]
+ params {
+ @in loop: Efl.Loop; [[ ]]
+ @in klass: const(Efl.Class); [[ ]]
+ }
+ return: Efl.Loop.Message.Handler; [[ ]]
+ }
+ message_process {
+ [[ ]]
+ return: bool; [[ ]]
+ }
+ message_exists {
+ [[ ]]
+ return: bool; [[ ]]
+ }
}
events {
idle,enter @restart; [[Event occurs once the main loop enters the idle state.]]
diff --git a/src/lib/ecore/efl_loop_handler.c b/src/lib/ecore/efl_loop_handler.c
new file mode 100644
index 0000000000..417e12d974
--- /dev/null
+++ b/src/lib/ecore/efl_loop_handler.c
@@ -0,0 +1,341 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+
+#include "ecore_private.h"
+
+#define MY_CLASS EFL_LOOP_HANDLER_CLASS
+
+//////////////////////////////////////////////////////////////////////////
+
+typedef struct _Efl_Loop_Handler_Data Efl_Loop_Handler_Data;
+
+struct _Efl_Loop_Handler_Data
+{
+ Eo *loop;
+ Efl_Loop_Data *loop_data;
+ Ecore_Fd_Handler *handler_fd;
+ Ecore_Win32_Handler *handler_win32;
+
+ void *win32;
+ int fd;
+
+ struct {
+ unsigned short read;
+ unsigned short write;
+ unsigned short error;
+ unsigned short buffer;
+ unsigned short prepare;
+ } references;
+
+ Efl_Loop_Handler_Flags flags : 8;
+ Eina_Bool file : 1;
+
+ Eina_Bool constructed : 1;
+ Eina_Bool finalized : 1;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+static Eina_Bool _cb_handler_fd(void *data, Ecore_Fd_Handler *fd_handler);
+static Eina_Bool _cb_handler_buffer(void *data, Ecore_Fd_Handler *fd_handler);
+static Eina_Bool _cb_handler_win32(void *data, Ecore_Win32_Handler *win32_handler);
+static void _cb_handler_prepare(void *data, Ecore_Fd_Handler *fd_handler);
+
+//////////////////////////////////////////////////////////////////////////
+
+static void
+_handler_clear(Efl_Loop_Handler_Data *pd)
+{
+ Eo *obj = pd->loop;
+ Efl_Loop_Data *loop = pd->loop_data;
+
+ if (pd->handler_fd)
+ _ecore_main_fd_handler_del(obj, loop, pd->handler_fd);
+ else if (pd->handler_win32)
+ _ecore_main_win32_handler_del(obj, loop, pd->handler_win32);
+ pd->handler_fd = NULL;
+ pd->handler_win32 = NULL;
+}
+
+static Ecore_Fd_Handler_Flags
+_handler_flags_get(Efl_Loop_Handler_Data *pd)
+{
+ return ((pd->references.read > 0) ? ECORE_FD_READ : 0) |
+ ((pd->references.write > 0) ? ECORE_FD_WRITE : 0) |
+ ((pd->references.error > 0) ? ECORE_FD_ERROR : 0);
+}
+
+static void
+_handler_active_update(Eo *obj, Efl_Loop_Handler_Data *pd)
+{
+ Ecore_Fd_Handler_Flags flags = _handler_flags_get(pd);
+
+ ecore_main_fd_handler_active_set(pd->handler_fd, flags);
+ if (pd->references.prepare)
+ ecore_main_fd_handler_prepare_callback_set
+ (pd->handler_fd, _cb_handler_prepare, obj);
+ else
+ ecore_main_fd_handler_prepare_callback_set
+ (pd->handler_fd, NULL, NULL);
+}
+
+static void
+_handler_reset(Eo *obj, Efl_Loop_Handler_Data *pd)
+{
+ if ((pd->fd < 0) && (!pd->win32))
+ {
+ _handler_clear(pd);
+ return;
+ }
+
+ if ((!pd->constructed) || (!pd->finalized)) return;
+
+ if (pd->fd >= 0)
+ {
+ Ecore_Fd_Cb buffer_func = NULL;
+ void *buffer_data = NULL;
+
+ if (pd->references.buffer > 0)
+ {
+ buffer_func = _cb_handler_buffer;
+ buffer_data = obj;
+ }
+
+ if (pd->handler_fd)
+ _handler_active_update(obj, pd);
+ else
+ {
+ Ecore_Fd_Handler_Flags flags = _handler_flags_get(pd);
+
+ if (pd->file)
+ pd->handler_fd = _ecore_main_fd_handler_add
+ (pd->loop, pd->loop_data, obj, pd->fd, flags,
+ _cb_handler_fd, obj, buffer_func, buffer_data,
+ EINA_TRUE);
+ else
+ pd->handler_fd = _ecore_main_fd_handler_add
+ (pd->loop, pd->loop_data, obj, pd->fd, flags,
+ _cb_handler_fd, obj, buffer_func, buffer_data,
+ EINA_FALSE);
+ if (pd->handler_fd) _handler_active_update(obj, pd);
+ }
+ }
+ else if (pd->win32)
+ {
+ pd->handler_win32 = _ecore_main_win32_handler_add
+ (pd->loop, pd->loop_data, obj, pd->win32, _cb_handler_win32, obj);
+ }
+}
+
+static Eina_Bool
+_event_references_update(Efl_Loop_Handler_Data *pd, const Efl_Event *event, int increment)
+{
+ const Efl_Callback_Array_Item *array = event->info;
+ int i;
+ Eina_Bool need_reset = EINA_FALSE;
+
+ for (i = 0; array[i].desc != NULL; i++)
+ {
+#define REFERENCES_MAP(_desc, _refs) \
+ if (array[i].desc == _desc) { \
+ pd->references._refs += increment; \
+ need_reset = EINA_TRUE; \
+ continue; \
+ }
+ REFERENCES_MAP(EFL_LOOP_HANDLER_EVENT_READ, read);
+ REFERENCES_MAP(EFL_LOOP_HANDLER_EVENT_WRITE, write);
+ REFERENCES_MAP(EFL_LOOP_HANDLER_EVENT_ERROR, error);
+ REFERENCES_MAP(EFL_LOOP_HANDLER_EVENT_BUFFER, buffer);
+ REFERENCES_MAP(EFL_LOOP_HANDLER_EVENT_PREPARE, prepare);
+ }
+ return need_reset;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+static Eina_Bool
+_cb_handler_fd(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+{
+ Eo *obj = data;
+
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+ efl_event_callback_call(obj, EFL_LOOP_HANDLER_EVENT_READ, NULL);
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
+ efl_event_callback_call(obj, EFL_LOOP_HANDLER_EVENT_WRITE, NULL);
+ if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
+ efl_event_callback_call(obj, EFL_LOOP_HANDLER_EVENT_ERROR, NULL);
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_cb_handler_buffer(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+{
+ Eo *obj = data;
+
+ efl_event_callback_call(obj, EFL_LOOP_HANDLER_EVENT_BUFFER, NULL);
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_cb_handler_win32(void *data, Ecore_Win32_Handler *win32_handler EINA_UNUSED)
+{
+ Eo *obj = data;
+
+ efl_event_callback_call(obj, EFL_LOOP_HANDLER_EVENT_READ, NULL);
+ return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_cb_handler_prepare(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+{
+ Eo *obj = data;
+
+ efl_event_callback_call(obj, EFL_LOOP_HANDLER_EVENT_PREPARE, NULL);
+}
+
+static void
+_cb_event_callback_add(void *data, const Efl_Event *event)
+{
+ Efl_Loop_Handler_Data *pd = data;
+ if (_event_references_update(pd, event, 1))
+ _handler_reset(event->object, pd);
+}
+
+static void
+_cb_event_callback_del(void *data, const Efl_Event *event)
+{
+ Efl_Loop_Handler_Data *pd = data;
+ if (_event_references_update(pd, event, -1))
+ _handler_reset(event->object, pd);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+EFL_CALLBACKS_ARRAY_DEFINE(_event_callback_watch,
+ { EFL_EVENT_CALLBACK_ADD, _cb_event_callback_add },
+ { EFL_EVENT_CALLBACK_DEL, _cb_event_callback_del });
+
+static void
+_efl_loop_handler_active_set(Eo *obj, Efl_Loop_Handler_Data *pd, Efl_Loop_Handler_Flags flags)
+{
+ pd->flags = flags;
+ _handler_reset(obj, pd);
+}
+
+static Efl_Loop_Handler_Flags
+_efl_loop_handler_active_get(Eo *obj EINA_UNUSED, Efl_Loop_Handler_Data *pd)
+{
+ return pd->flags;
+}
+
+static void
+_efl_loop_handler_fd_set(Eo *obj, Efl_Loop_Handler_Data *pd, int fd)
+{
+ pd->fd = fd;
+ pd->file = EINA_FALSE;
+ pd->win32 = NULL;
+ _handler_reset(obj, pd);
+}
+
+static int
+_efl_loop_handler_fd_get(Eo *obj EINA_UNUSED, Efl_Loop_Handler_Data *pd)
+{
+ if (pd->win32) return -1;
+ return pd->file ? -1 : pd->fd;
+}
+
+static void
+_efl_loop_handler_fd_file_set(Eo *obj, Efl_Loop_Handler_Data *pd, int fd)
+{
+ pd->fd = fd;
+ pd->file = EINA_TRUE;
+ pd->win32 = NULL;
+ _handler_reset(obj, pd);
+}
+
+static int
+_efl_loop_handler_fd_file_get(Eo *obj EINA_UNUSED, Efl_Loop_Handler_Data *pd)
+{
+ if (pd->win32) return -1;
+ return pd->file ? pd->fd : -1;
+}
+
+static void
+_efl_loop_handler_win32_set(Eo *obj, Efl_Loop_Handler_Data *pd, void *handle)
+{
+ pd->fd = -1;
+ pd->file = EINA_FALSE;
+ pd->win32 = handle;
+ _handler_reset(obj, pd);
+}
+
+static void *
+_efl_loop_handler_win32_get(Eo *obj EINA_UNUSED, Efl_Loop_Handler_Data *pd)
+{
+ return pd->win32;
+}
+
+static void
+_efl_loop_handler_efl_object_parent_set(Eo *obj, Efl_Loop_Handler_Data *pd, Efl_Object *parent)
+{
+ efl_parent_set(efl_super(obj, MY_CLASS), parent);
+
+ if ((!pd->constructed) || (!pd->finalized)) return;
+
+ _handler_clear(pd);
+
+ if (pd->loop)
+ {
+ pd->loop_data->fd_handlers_obj = eina_list_remove
+ (pd->loop_data->fd_handlers_obj, obj);
+ pd->loop = NULL;
+ pd->loop_data = NULL;
+ }
+
+ if (parent == NULL) return;
+
+ pd->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
+ pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS);
+ if (pd->loop_data)
+ pd->loop_data->fd_handlers_obj =
+ eina_list_append(pd->loop_data->fd_handlers_obj, obj);
+ _handler_reset(obj, pd);
+}
+
+static Efl_Object *
+_efl_loop_handler_efl_object_constructor(Eo *obj, Efl_Loop_Handler_Data *pd)
+{
+ efl_constructor(efl_super(obj, MY_CLASS));
+ efl_event_callback_array_add(obj, _event_callback_watch(), pd);
+ pd->constructed = EINA_TRUE;
+ return obj;
+}
+
+static Efl_Object *
+_efl_loop_handler_efl_object_finalize(Eo *obj, Efl_Loop_Handler_Data *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_data)
+ pd->loop_data->fd_handlers_obj =
+ eina_list_append(pd->loop_data->fd_handlers_obj, obj);
+ pd->finalized = EINA_TRUE;
+ _handler_reset(obj, pd);
+ return efl_finalize(efl_super(obj, MY_CLASS));
+}
+
+static void
+_efl_loop_handler_efl_object_destructor(Eo *obj, Efl_Loop_Handler_Data *pd)
+{
+ efl_destructor(efl_super(obj, MY_CLASS));
+
+ if (pd->loop_data)
+ pd->loop_data->fd_handlers_obj =
+ eina_list_remove(pd->loop_data->fd_handlers_obj, obj);
+ _handler_clear(pd);
+}
+
+#include "efl_loop_handler.eo.c"
diff --git a/src/lib/ecore/efl_loop_handler.eo b/src/lib/ecore/efl_loop_handler.eo
new file mode 100644
index 0000000000..02d1109486
--- /dev/null
+++ b/src/lib/ecore/efl_loop_handler.eo
@@ -0,0 +1,72 @@
+import eina_types;
+
+enum Efl.Loop.Handler.Flags {
+ [[ A set of flags that can be OR'd together to indicate which are
+ desired ]]
+ none = 0, [[ No I/O is desired (generally useless) ]]
+ read = 1, [[ Reading is desired ]]
+ write = 2, [[ Writing is desired ]]
+ error = 4, [[ Error channel input is desired ]]
+}
+
+class Efl.Loop.Handler (Efl.Object)
+{
+ [[ An object that describes an low-level source of I/O to listen to
+ for available data to be read or written, depending on the OS and data
+ source type. When I/O becomes available various events are produced
+ and the callbacks attached to them will be called. ]]
+ methods {
+ @property active {
+ [[ This sets what kind of I/O should be listened to only when
+ using a fd or fd_file for the handler ]]
+ set { }
+ get { }
+ values {
+ flags: Efl.Loop.Handler.Flags; [[ The flags that indicate what kind of I/O should be listened for like read, write or error channels. ]]
+ }
+ }
+ @property fd {
+ [[ Controls a file desciptor to listen to for I/O that points
+ to a data pipe such as a device, socket or pipe etc. ]]
+ set { }
+ get { }
+ values {
+ fd: int; [[ The file descriptor ]]
+ }
+ }
+ @property fd_file {
+ [[ Controls a file descriptor to listen to for I/O that
+ specifically points to a file in storage and not a device, socket or
+ pipe etc. ]]
+ set { }
+ get { }
+ values {
+ fd: int; [[ The file descriptor ]]
+ }
+ }
+ @property win32 {
+ [[ Controls a windows win32 object handle to listen to for I/O.
+ When it becomes available for any data the read event will be
+ produced. ]]
+ set { }
+ get { }
+ values {
+ handle: void_ptr; [[ A win32 object handle ]]
+ }
+ }
+ }
+ events {
+ read; [[ Called when a read happened on the descriptor ]]
+ write; [[ Called when a write happened on the descriptor ]]
+ error; [[ Called when a error occurred on the descriptor ]]
+ buffer; [[ Called when buffered data already read from the descriptor should be processed ]]
+ prepare; [[ Called when preparing a descriptor for listening ]]
+ }
+
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ Efl.Object.finalize;
+ Efl.Object.parent { set; }
+ }
+}
diff --git a/src/lib/ecore/efl_loop_message.c b/src/lib/ecore/efl_loop_message.c
new file mode 100644
index 0000000000..dc93020e6f
--- /dev/null
+++ b/src/lib/ecore/efl_loop_message.c
@@ -0,0 +1,83 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#define MY_CLASS EFL_LOOP_MESSAGE_CLASS
+
+#include "ecore_main_common.h"
+
+typedef struct _Efl_Loop_Message_Data Efl_Loop_Message_Data;
+
+struct _Efl_Loop_Message_Data
+{
+ Eina_Inlist *send_list_node;
+ Eo *loop;
+ Efl_Loop_Data *loop_data;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+void
+_efl_loop_message_send_info_set(Eo *obj, Eina_Inlist *node, Eo *loop, Efl_Loop_Data *loop_data)
+{
+ Efl_Loop_Message_Data *pd = efl_data_scope_get(obj, MY_CLASS);
+ if (!pd) return;
+ pd->send_list_node = node;
+ pd->loop = loop;
+ pd->loop_data = loop_data;
+}
+
+void
+_efl_loop_message_unsend(Eo *obj)
+{
+ Efl_Loop_Message_Data *pd = efl_data_scope_get(obj, MY_CLASS);
+ if (!pd) return;
+ if ((!pd->send_list_node) || (!pd->loop)) return;
+
+ Message *msg = (Message *)pd->send_list_node;
+ msg->delete_me = EINA_TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+EOLIAN static Efl_Object *
+_efl_loop_message_efl_object_constructor(Eo *obj, Efl_Loop_Message_Data *pd EINA_UNUSED)
+{
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+ return obj;
+}
+
+EOLIAN static void
+_efl_loop_message_efl_object_destructor(Eo *obj, Efl_Loop_Message_Data *pd)
+{
+ if ((pd->send_list_node) && (pd->loop_data))
+ {
+ Message *msg = (Message *)pd->send_list_node;
+
+ msg->delete_me = EINA_TRUE;
+ msg->message = NULL;
+ msg->handler = NULL;
+ if (pd->loop_data->message_walking == 0)
+ {
+ pd->loop_data->message_queue =
+ eina_inlist_remove(pd->loop_data->message_queue,
+ pd->send_list_node);
+ }
+ pd->send_list_node = NULL;
+ pd->loop = NULL;
+ pd->loop_data = NULL;
+ free(pd->send_list_node);
+ }
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+#include "efl_loop_message.eo.c"
diff --git a/src/lib/ecore/efl_loop_message.eo b/src/lib/ecore/efl_loop_message.eo
new file mode 100644
index 0000000000..7368c28802
--- /dev/null
+++ b/src/lib/ecore/efl_loop_message.eo
@@ -0,0 +1,13 @@
+import efl_types;
+import eina_types;
+
+class Efl.Loop.Message (Efl.Object)
+{
+ [[ ]]
+ methods {
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ }
+}
diff --git a/src/lib/ecore/efl_loop_message_handler.c b/src/lib/ecore/efl_loop_message_handler.c
new file mode 100644
index 0000000000..04862da756
--- /dev/null
+++ b/src/lib/ecore/efl_loop_message_handler.c
@@ -0,0 +1,145 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "Ecore.h"
+#include "ecore_private.h"
+
+#define MY_CLASS EFL_LOOP_MESSAGE_HANDLER_CLASS
+
+#include "ecore_main_common.h"
+
+typedef struct _Efl_Loop_Message_Handler_Data Efl_Loop_Message_Handler_Data;
+
+struct _Efl_Loop_Message_Handler_Data
+{
+ Eo *loop;
+ Efl_Loop_Data *loop_data;
+};
+
+EOLIAN static Efl_Loop_Message *
+_efl_loop_message_handler_message_add(Eo *obj, Efl_Loop_Message_Handler_Data *pd EINA_UNUSED)
+{
+ // XXX: implement message object cache
+ Efl_Loop_Message *message = efl_add(EFL_LOOP_MESSAGE_CLASS, obj);
+ if (!message) return NULL;
+ // XXX: track added messages not sent yet ...
+ return message;
+}
+
+EOLIAN static void
+_efl_loop_message_handler_message_send(Eo *obj, Efl_Loop_Message_Handler_Data *pd, Efl_Loop_Message *message)
+{
+ Message *msg;
+
+ if (EINA_UNLIKELY(!pd->loop))
+ {
+ pd->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
+ if (!pd->loop) return;
+ pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS);
+ if (!pd->loop_data)
+ {
+ pd->loop = NULL;
+ return;
+ }
+ }
+ msg = calloc(1, sizeof(Message));
+ if (msg)
+ {
+ msg->handler = obj;
+ msg->message = message;
+ pd->loop_data->message_queue = eina_inlist_append
+ (pd->loop_data->message_queue, EINA_INLIST_GET(msg));
+ _efl_loop_message_send_info_set(message, EINA_INLIST_GET(msg),
+ pd->loop, pd->loop_data);
+ return;
+ }
+ efl_del(message);
+}
+
+EOLIAN static void
+_efl_loop_message_handler_message_call(Eo *obj, Efl_Loop_Message_Handler_Data *pd, Efl_Loop_Message *message)
+{
+ Message *msg;
+ unsigned int n = 0;
+ Eina_Bool found = EINA_FALSE;
+
+ if (!pd->loop) return;
+ EINA_INLIST_FOREACH(pd->loop_data->message_queue, msg)
+ {
+ n++;
+ if (msg->message != message) continue;
+ found = EINA_TRUE;
+ msg->message = NULL;
+ msg->handler = NULL;
+ _efl_loop_message_send_info_set(message, NULL, NULL, NULL);
+ if ((pd->loop_data->message_walking == 0) || (n == 1))
+ {
+ pd->loop_data->message_queue =
+ eina_inlist_remove(pd->loop_data->message_queue,
+ EINA_INLIST_GET(msg));
+ free(msg);
+ }
+ else
+ msg->delete_me = EINA_TRUE;
+ break;
+ }
+ efl_event_callback_call(obj, EFL_LOOP_MESSAGE_HANDLER_EVENT_MESSAGE,
+ message);
+ // XXX: implement message object cache...
+ if (message) efl_del(message);
+ if (found) return;
+ ERR("Cannot find message called object %p on message queue", message);
+}
+
+EOLIAN static Eina_Bool
+_efl_loop_message_handler_message_clear(Eo *obj, Efl_Loop_Message_Handler_Data *pd)
+{
+ Eina_Inlist *tmp;
+ Message *msg;
+
+ if (!pd->loop) return EINA_FALSE;
+ if (!pd->loop_data->message_queue) return EINA_FALSE;
+ EINA_INLIST_FOREACH_SAFE(pd->loop_data->message_queue, tmp, msg)
+ {
+ if (msg->handler == obj)
+ {
+ Eo *message = msg->message;
+
+ msg->delete_me = EINA_TRUE;
+ msg->handler = NULL;
+ msg->message = NULL;
+ _efl_loop_message_send_info_set(message, NULL, NULL, NULL);
+ if (pd->loop_data->message_walking == 0)
+ {
+ pd->loop_data->message_queue =
+ eina_inlist_remove(pd->loop_data->message_queue,
+ EINA_INLIST_GET(msg));
+ free(msg);
+ }
+ if (message) efl_del(message);
+ }
+ }
+ return EINA_FALSE;
+}
+
+EOLIAN static Efl_Object *
+_efl_loop_message_handler_efl_object_constructor(Eo *obj, Efl_Loop_Message_Handler_Data *pd EINA_UNUSED)
+{
+ obj = efl_constructor(efl_super(obj, MY_CLASS));
+ return obj;
+}
+
+EOLIAN static void
+_efl_loop_message_handler_efl_object_destructor(Eo *obj, Efl_Loop_Message_Handler_Data *pd EINA_UNUSED)
+{
+ efl_destructor(efl_super(obj, MY_CLASS));
+}
+
+#include "efl_loop_message_handler.eo.c"
diff --git a/src/lib/ecore/efl_loop_message_handler.eo b/src/lib/ecore/efl_loop_message_handler.eo
new file mode 100644
index 0000000000..b934364013
--- /dev/null
+++ b/src/lib/ecore/efl_loop_message_handler.eo
@@ -0,0 +1,38 @@
+import efl_types;
+import eina_types;
+
+class Efl.Loop.Message.Handler (Efl.Object)
+{
+ [[ ]]
+ methods {
+ message_add {
+ [[ ]]
+ return: Efl.Loop.Message; [[ ]]
+ }
+ message_send {
+ [[ Plase the message on the queue to be called later ]]
+ params {
+ @in message: Efl.Loop.Message; [[ ]]
+ }
+ }
+ message_call {
+ [[ Overide me (implement) then call super after calling the
+ right callback type if you specialize the message type
+ ]]
+ params {
+ @in message: Efl.Loop.Message; [[ Generic message event type ]]
+ }
+ }
+ message_clear {
+ [[ ]]
+ return: bool; [[ ]]
+ }
+ }
+ events {
+ message: Efl.Loop.Message; [[ ]]
+ }
+ implements {
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ }
+}
diff --git a/src/lib/ecore/efl_promise.c b/src/lib/ecore/efl_promise.c
index f95e12940e..17e95489c6 100644
--- a/src/lib/ecore/efl_promise.c
+++ b/src/lib/ecore/efl_promise.c
@@ -21,6 +21,8 @@ struct _Efl_Promise_Msg
struct _Efl_Promise_Data
{
+ Eo *loop;
+ Efl_Loop_Data *loop_data;
Efl_Promise *promise;
Efl_Promise_Msg *message;
Eina_List *futures;
@@ -589,7 +591,6 @@ void
ecore_loop_promise_fulfill(Eo *obj)
{
Efl_Promise_Data *pd = efl_data_scope_get(obj, EFL_PROMISE_CLASS);
-
_efl_promise_propagate(obj, pd);
}
@@ -675,16 +676,8 @@ _efl_promise_progress_set(Eo *obj, Efl_Promise_Data *pd, const void *p)
}
}
-static Efl_Object *
-_efl_promise_efl_object_constructor(Eo *obj, Efl_Promise_Data *pd)
-{
- pd->promise = obj;
-
- return efl_constructor(efl_super(obj, EFL_PROMISE_CLASS));
-}
-
static void
-_efl_promise_efl_object_destructor(Eo *obj, Efl_Promise_Data *pd)
+_efl_promise_loop_clear(Eo *obj, Efl_Promise_Data *pd)
{
pd->nodelay = EINA_TRUE;
@@ -698,7 +691,7 @@ _efl_promise_efl_object_destructor(Eo *obj, Efl_Promise_Data *pd)
if (pd->message &&
!pd->propagated)
{
- ecore_loop_promise_unregister(efl_provider_find(obj, EFL_LOOP_CLASS), obj);
+ ecore_loop_promise_unregister(pd->loop, obj);
_efl_promise_propagate(obj, pd);
}
@@ -708,7 +701,28 @@ _efl_promise_efl_object_destructor(Eo *obj, Efl_Promise_Data *pd)
_efl_promise_msg_free(pd->message);
pd->message = NULL;
}
+}
+
+static void
+_efl_promise_efl_object_parent_set(Eo *obj, Efl_Promise_Data *pd, Efl_Object *parent)
+{
+ if (!parent) _efl_promise_loop_clear(obj, pd);
+ efl_parent_set(efl_super(obj, EFL_PROMISE_CLASS), parent);
+ pd->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
+ pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS);
+}
+static Efl_Object *
+_efl_promise_efl_object_constructor(Eo *obj, Efl_Promise_Data *pd)
+{
+ pd->promise = obj;
+ return efl_constructor(efl_super(obj, EFL_PROMISE_CLASS));
+}
+
+static void
+_efl_promise_efl_object_destructor(Eo *obj, Efl_Promise_Data *pd)
+{
+ _efl_promise_loop_clear(obj, pd);
efl_destructor(efl_super(obj, EFL_PROMISE_CLASS));
}
diff --git a/src/lib/ecore/efl_promise.eo b/src/lib/ecore/efl_promise.eo
index 40a164b343..be1a7dcd3c 100644
--- a/src/lib/ecore/efl_promise.eo
+++ b/src/lib/ecore/efl_promise.eo
@@ -73,5 +73,6 @@ class Efl.Promise (Efl.Loop.Consumer)
implements {
Efl.Object.destructor;
Efl.Object.constructor;
+ Efl.Object.parent { set; }
}
}