ecore - begin moving data into the efl loop data in the object
we really should have data inside the loop object, so begin moving it one small thing at a time. this is the basics that will allow multiple efl loops. make an eo efl object and class for fd handlers that is efl loop bound make fd handlers really bound to their parent loop and not global as well as have a nice class/obj. create an message queue per loop and put legacy ecore events on top of it... and a lot more. this is not 100% done, but it's a lot of the core and groundwork. various ecore_timer_add(), ecore_diler_add() etc. need changes. The following still need doing: ecore_timer (internal usage for sure) ecore_idler (internal usage for sure) ecore_idle_enterer ecore_idle_exiter ecore_pollers? (is the new efl loop stuff ok?) ecore_exe (fork/spawn from any thread and track exe from that thread?) ecore_signal code ecore_throttle (should we have a single global too? we have per loop) ecore_app ? (should every loop be given its own argv/argc?) Lots of internal ecore code uses/calls these legacy calls and we should have efl loop replacements and/or use the ones we have The following will bedifferently designed for loop to loop control/messaging/ipc: ecore_thread ecore_pipe
This commit is contained in:
parent
ccfa9ae220
commit
5dd52fd09b
|
@ -3,12 +3,17 @@
|
|||
|
||||
ecore_eolian_files_legacy = \
|
||||
lib/ecore/ecore_exe.eo \
|
||||
lib/ecore/ecore_event_message.eo \
|
||||
lib/ecore/ecore_event_message_handler.eo \
|
||||
lib/ecore/efl_loop_timer.eo
|
||||
|
||||
ecore_eolian_files_public = \
|
||||
lib/ecore/efl_loop.eo \
|
||||
lib/ecore/efl_loop_consumer.eo \
|
||||
lib/ecore/efl_loop_fd.eo \
|
||||
lib/ecore/efl_loop_handler.eo \
|
||||
lib/ecore/efl_loop_message.eo \
|
||||
lib/ecore/efl_loop_message_handler.eo \
|
||||
lib/ecore/efl_io_closer_fd.eo \
|
||||
lib/ecore/efl_io_positioner_fd.eo \
|
||||
lib/ecore/efl_io_reader_fd.eo \
|
||||
|
@ -84,8 +89,14 @@ lib/ecore/ecore_idle_exiter.c \
|
|||
lib/ecore/ecore_idler.c \
|
||||
lib/ecore/ecore_job.c \
|
||||
lib/ecore/ecore_main.c \
|
||||
lib/ecore/ecore_event_message.c \
|
||||
lib/ecore/ecore_event_message_handler.c \
|
||||
lib/ecore/efl_loop.c \
|
||||
lib/ecore/efl_loop_consumer.c \
|
||||
lib/ecore/efl_loop_fd.c \
|
||||
lib/ecore/efl_loop_handler.c \
|
||||
lib/ecore/efl_loop_message.c \
|
||||
lib/ecore/efl_loop_message_handler.c \
|
||||
lib/ecore/efl_io_closer_fd.c \
|
||||
lib/ecore/efl_io_positioner_fd.c \
|
||||
lib/ecore/efl_io_reader_fd.c \
|
||||
|
@ -115,6 +126,7 @@ lib/ecore/efl_interpolator_divisor.c \
|
|||
lib/ecore/efl_interpolator_bounce.c \
|
||||
lib/ecore/efl_interpolator_spring.c \
|
||||
lib/ecore/efl_interpolator_cubic_bezier.c \
|
||||
lib/ecore/ecore_main_timechanges.c \
|
||||
lib/ecore/ecore_pipe.c \
|
||||
lib/ecore/ecore_poller.c \
|
||||
lib/ecore/ecore_time.c \
|
||||
|
@ -124,7 +136,9 @@ lib/ecore/ecore_throttle.c \
|
|||
lib/ecore/ecore_exe.c \
|
||||
lib/ecore/ecore_exe_private.h \
|
||||
lib/ecore/ecore_private.h \
|
||||
lib/ecore/ecore_internal.h
|
||||
lib/ecore/ecore_internal.h \
|
||||
lib/ecore/ecore_main_common.h
|
||||
|
||||
|
||||
if HAVE_WIN32
|
||||
lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_exe_win32.c
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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"
|
|
@ -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 ]]
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
//////
|
||||
// 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_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);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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 ((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));
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// 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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
Ecore_Timer *poll_high;
|
||||
Ecore_Timer *poll_medium;
|
||||
Ecore_Timer *poll_low;
|
||||
|
||||
int idlers;
|
||||
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;
|
||||
|
||||
Eina_Inarray *message_handlers;
|
||||
Eina_Inlist *message_queue;
|
||||
unsigned int message_walking;
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
typedef struct _Ecore_Timer_Legacy Ecore_Timer_Legacy;
|
||||
|
||||
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 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 Eina_Inlist *timers = NULL;
|
||||
static Eina_Inlist *suspended = NULL;
|
||||
|
||||
static Efl_Loop_Timer_Data *timer_current = NULL;
|
||||
|
||||
static int timers_added = 0;
|
||||
|
||||
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;
|
||||
|
||||
if (pd->in < 0)
|
||||
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.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);
|
||||
|
||||
pd->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
|
||||
pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS);
|
||||
|
||||
if (efl_parent_get(obj) != parent) return;
|
||||
|
||||
_efl_loop_timer_util_instanciate(pd->loop_data, pd);
|
||||
|
||||
if (parent != NULL) pd->noparent = EINA_FALSE;
|
||||
else pd->noparent = EINA_TRUE;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_loop_timer_efl_object_destructor(Eo *obj, Efl_Loop_Timer_Data *pd)
|
||||
{
|
||||
Eina_Inlist *first;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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_loop_clear(pd);
|
||||
efl_destructor(efl_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
void
|
||||
_efl_loop_timer_shutdown(void)
|
||||
{
|
||||
timer_current = NULL;
|
||||
}
|
||||
|
||||
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"
|
||||
|
|
|
@ -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"
|
|
@ -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.]]
|
||||
|
|
|
@ -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"
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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"
|
|
@ -0,0 +1,13 @@
|
|||
import efl_types;
|
||||
import eina_types;
|
||||
|
||||
class Efl.Loop.Message (Efl.Object)
|
||||
{
|
||||
[[ ]]
|
||||
methods {
|
||||
}
|
||||
implements {
|
||||
Efl.Object.constructor;
|
||||
Efl.Object.destructor;
|
||||
}
|
||||
}
|
|
@ -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"
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -73,5 +73,6 @@ class Efl.Promise (Efl.Loop.Consumer)
|
|||
implements {
|
||||
Efl.Object.destructor;
|
||||
Efl.Object.constructor;
|
||||
Efl.Object.parent { set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue