],
[have_threads="no"])
+### enable thread safety if we have threads, unless specifically asked not to
+if test "x${have_threads}" = "xno"
+then
+ want_thread_safety="no"
+else
+ want_thread_safety="no" # to be changed to yes when ready
+ AC_ARG_ENABLE(thread-safety,
+ AC_HELP_STRING([--enable-thread-safety], [enable or disable thread safety]),
+ [want_thread_safety=$enableval])
+fi
+
+if test "x${want_thread_safety}" = "xyes"
+then
+ AC_DEFINE([HAVE_THREAD_SAFETY], [1], [Define to enable thread safety])
+fi
+
### Checks for types
AC_CHECK_SIZEOF(int, 4)
AC_CHECK_SIZEOF(long, 4)
echo
echo " Ecore........................: always"
echo " Thread support.............: $have_threads"
+echo " Thread safety..............: $want_thread_safety"
echo " GLib support...............: $have_glib"
echo " Always integrate GLib......: $want_glib_integration_always"
echo " Use g_main_loop............: $want_g_main_loop"
double t_loop = ecore_loop_time_get();
double sync_0 = 0.0;
double d = -fmod(t_loop - sync_0, animators_frametime);
-
- timer = ecore_timer_loop_add(animators_frametime,
- _ecore_animator, NULL);
- ecore_timer_delay(timer, d);
+
+ timer = _ecore_timer_loop_add(animators_frametime,
+ _ecore_animator, NULL);
+ _ecore_timer_delay(timer, d);
}
break;
case ECORE_ANIMATOR_SOURCE_CUSTOM:
case ECORE_ANIMATOR_SOURCE_TIMER:
if (timer)
{
- ecore_timer_del(timer);
+ _ecore_timer_del(timer);
timer = NULL;
}
break;
{
if (!animator->delete_me && !animator->suspended)
{
- if (!animator->func(animator->data))
+ Ecore_Task_Cb func;
+ void *data;
+ Eina_Bool ret;
+
+ func = animator->func;
+ data = animator->data;
+ _ecore_unlock();
+ ret = func(data);
+ _ecore_lock();
+
+ if (!ret)
{
animator->delete_me = EINA_TRUE;
animators_delete_me++;
EAPI Ecore_Animator *
ecore_animator_add(Ecore_Task_Cb func, const void *data)
{
- Ecore_Animator *animator;
+ Ecore_Animator *animator = NULL;
- ECORE_MAIN_LOOP_ASSERT();
-
- if (!func) return NULL;
+ _ecore_lock();
+ if (!func) goto unlock;
animator = calloc(1, sizeof(Ecore_Animator));
- if (!animator) return NULL;
+ if (!animator) goto unlock;
ECORE_MAGIC_SET(animator, ECORE_MAGIC_ANIMATOR);
animator->func = func;
animator->data = (void *)data;
animators = (Ecore_Animator *)eina_inlist_append(EINA_INLIST_GET(animators), EINA_INLIST_GET(animator));
_begin_tick();
+unlock:
+ _ecore_unlock();
return animator;
}
{
Ecore_Animator *animator;
- ECORE_MAIN_LOOP_ASSERT();
-
+ _ecore_lock();
if (runtime <= 0.0) runtime = 0.0;
animator = ecore_animator_add(_ecore_animator_run, NULL);
animator->data = animator;
animator->run_data = (void *)data;
animator->start = ecore_loop_time_get();
animator->run = runtime;
+ _ecore_unlock();
return animator;
}
EAPI double
ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2)
{
+ /* purely functional - locking not required */
if (pos > 1.0) pos = 1.0;
else if (pos < 0.0) pos = 0.0;
switch (map)
EAPI void *
ecore_animator_del(Ecore_Animator *animator)
{
- ECORE_MAIN_LOOP_ASSERT();
+ void *data = NULL;
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
{
ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
"ecore_animator_del");
- return NULL;
+ goto unlock;
+ }
+ if (animator->delete_me)
+ {
+ data = animator->data;
+ goto unlock;
}
- if (animator->delete_me) return animator->data;
animator->delete_me = EINA_TRUE;
animators_delete_me++;
- if (animator->run_func) return animator->run_data;
- return animator->data;
+ if (animator->run_func)
+ data = animator->run_data;
+ else
+ data = animator->data;
+unlock:
+ _ecore_unlock();
+ return data;
}
EAPI void
ecore_animator_frametime_set(double frametime)
{
- ECORE_MAIN_LOOP_ASSERT();
-
+ _ecore_lock();
if (frametime < 0.0) frametime = 0.0;
- if (animators_frametime == frametime) return;
+ if (animators_frametime == frametime) goto unlock;
animators_frametime = frametime;
_end_tick();
if (animators) _begin_tick();
+unlock:
+ _ecore_unlock();
}
EAPI double
EAPI void
ecore_animator_freeze(Ecore_Animator *animator)
{
- ECORE_MAIN_LOOP_ASSERT();
-
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
{
ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
"ecore_animator_del");
- return;
+ goto unlock;
}
- if (animator->delete_me) return;
+ if (animator->delete_me) goto unlock;
animator->suspended = EINA_TRUE;
+unlock:
+ _ecore_unlock();
}
EAPI void
ecore_animator_thaw(Ecore_Animator *animator)
{
- ECORE_MAIN_LOOP_ASSERT();
-
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(animator, ECORE_MAGIC_ANIMATOR))
{
ECORE_MAGIC_FAIL(animator, ECORE_MAGIC_ANIMATOR,
"ecore_animator_del");
- return;
+ goto unlock;
}
- if (animator->delete_me) return;
+ if (animator->delete_me) goto unlock;
animator->suspended = EINA_FALSE;
+unlock:
+ _ecore_unlock();
}
EAPI void
ecore_animator_source_set(Ecore_Animator_Source source)
{
- ECORE_MAIN_LOOP_ASSERT();
-
+ _ecore_lock();
src = source;
_end_tick();
if (animators) _begin_tick();
+ _ecore_unlock();
}
EAPI Ecore_Animator_Source
ecore_animator_source_get(void)
{
- ECORE_MAIN_LOOP_ASSERT();
-
return src;
}
EAPI void
ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, const void *data)
{
- ECORE_MAIN_LOOP_ASSERT();
-
+ _ecore_lock();
begin_tick_cb = func;
begin_tick_data = data;
_end_tick();
if (animators) _begin_tick();
+ _ecore_unlock();
}
EAPI void
ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, const void *data)
{
- ECORE_MAIN_LOOP_ASSERT();
-
+ _ecore_lock();
end_tick_cb = func;
end_tick_data = data;
_end_tick();
if (animators) _begin_tick();
+ _ecore_unlock();
}
EAPI void
ecore_animator_custom_tick(void)
{
- ECORE_MAIN_LOOP_ASSERT();
-
+ _ecore_lock();
if (src == ECORE_ANIMATOR_SOURCE_CUSTOM) _do_tick();
+ _ecore_unlock();
}
void
static Eina_Bool
_ecore_animator(void *data __UNUSED__)
{
- return _do_tick();
+ Eina_Bool r;
+ _ecore_lock();
+ r = _do_tick();
+ _ecore_unlock();
+ return r;
}
EAPI Ecore_Event_Handler *
ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data)
{
- Ecore_Event_Handler *eh;
+ Ecore_Event_Handler *eh = NULL;
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
- if (!func) return NULL;
- if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) return NULL;
+ if (!func) goto unlock;
+ if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) goto unlock;
eh = calloc(1, sizeof(Ecore_Event_Handler));
- if (!eh) return NULL;
+ if (!eh) goto unlock;
ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER);
eh->type = type;
eh->func = func;
if (!new_handlers)
{
free(eh);
- return NULL;
+ goto unlock;
}
event_handlers = new_handlers;
for (i = p_alloc_num; i < event_handlers_alloc_num; i++)
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));
+
+unlock:
+ _ecore_unlock();
return eh;
}
EAPI void *
ecore_event_handler_del(Ecore_Event_Handler *event_handler)
{
- ECORE_MAIN_LOOP_ASSERT();
+ void *data = NULL;
+ _ecore_lock();
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;
+ goto unlock;
}
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;
+ data = event_handler->data;
+unlock:
+ _ecore_unlock();
+
+ return data;
}
/**
EAPI void *
ecore_event_handler_data_get(Ecore_Event_Handler *eh)
{
- ECORE_MAIN_LOOP_ASSERT();
+ void *data = NULL;
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER))
{
ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_get");
- return NULL;
+ goto unlock;
}
- return eh->data;
+ data = eh->data;
+unlock:
+ _ecore_unlock();
+ return data;
}
/**
EAPI void *
ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *data)
{
- void *old;
-
- ECORE_MAIN_LOOP_ASSERT();
+ void *old = NULL;
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER))
{
ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_set");
- return NULL;
+ goto unlock;
}
old = eh->data;
eh->data = (void *)data;
+unlock:
+ _ecore_unlock();
+
return old;
}
EAPI Ecore_Event *
ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data)
{
- ECORE_MAIN_LOOP_ASSERT();
+ Ecore_Event *event = NULL;
-/* if (!ev) return NULL;*/
- if (type <= ECORE_EVENT_NONE) return NULL;
- if (type >= event_id_max) return NULL;
+ _ecore_lock();
+
+/* if (!ev) goto unlock; */
+ if (type <= ECORE_EVENT_NONE) goto unlock;
+ if (type >= event_id_max) goto unlock;
if ((ev) && (!func_free)) func_free = _ecore_event_generic_free;
- return _ecore_event_add(type, ev, func_free, data);
+ event = _ecore_event_add(type, ev, func_free, data);
+unlock:
+ _ecore_unlock();
+ return event;
}
/**
EAPI void *
ecore_event_del(Ecore_Event *event)
{
- ECORE_MAIN_LOOP_ASSERT();
+ void *data = NULL;
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT))
{
ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, "ecore_event_del");
- return NULL;
+ goto unlock;
}
EINA_SAFETY_ON_TRUE_RETURN_VAL(event->delete_me, NULL);
event->delete_me = 1;
- return event->data;
+ data = event->data;
+unlock:
+ _ecore_unlock();
+ return data;
}
/**
EAPI int
ecore_event_type_new(void)
{
- ECORE_MAIN_LOOP_ASSERT();
+ int id;
- event_id_max++;
- return event_id_max - 1;
+ _ecore_lock();
+ id = event_id_max++;
+ _ecore_unlock();
+
+ return id;
}
/**
EAPI Ecore_Event_Filter *
ecore_event_filter_add(Ecore_Data_Cb func_start, Ecore_Filter_Cb func_filter, Ecore_End_Cb func_end, const void *data)
{
- Ecore_Event_Filter *ef;
-
- ECORE_MAIN_LOOP_ASSERT();
+ Ecore_Event_Filter *ef = NULL;
- if (!func_filter) return NULL;
+ _ecore_lock();
+ if (!func_filter) goto unlock;
ef = calloc(1, sizeof(Ecore_Event_Filter));
- if (!ef) return NULL;
+ if (!ef) goto unlock;
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));
+unlock:
+ _ecore_unlock();
return ef;
}
EAPI void *
ecore_event_filter_del(Ecore_Event_Filter *ef)
{
- ECORE_MAIN_LOOP_ASSERT();
+ void *data = NULL;
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER))
{
ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del");
- return NULL;
+ goto unlock;
}
EINA_SAFETY_ON_TRUE_RETURN_VAL(ef->delete_me, NULL);
ef->delete_me = 1;
event_filters_delete_me = 1;
- return ef->data;
+ data = ef->data;
+unlock:
+ _ecore_unlock();
+
+ return data;
}
/**
void *data;
data = event->data;
- if (event->func_free) event->func_free(event->data, event->event);
+ if (event->func_free)
+ {
+ Ecore_End_Cb func_free;
+ void *ev;
+ void *data;
+
+ func_free = event->func_free;
+ ev = event->event;
+ data = event->data;
+
+ _ecore_unlock();
+ func_free(data, ev);
+ _ecore_lock();
+ }
events = (Ecore_Event *) eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event));
ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE);
free(event);
ef->references++;
if (ef->func_start)
- ef->loop_data = ef->func_start(ef->data);
+ {
+ Ecore_Data_Cb func_start;
+ void *data;
+ void *r;
+
+ func_start = ef->func_start;
+ data = ef->data;
+ _ecore_unlock();
+ r = func_start(data);
+ _ecore_lock();
+ ef->loop_data = r;
+ }
if (!event_filter_event_current)
{
while (event_filter_event_current)
{
Ecore_Event *e = event_filter_event_current;
-
- if (!ef->func_filter(ef->data, ef->loop_data,
- e->type, e->event))
+ Ecore_Filter_Cb func_filter;
+ void *loop_data;
+ void *data;
+ int type;
+ void *event;
+ Eina_Bool r;
+
+ func_filter = ef->func_filter;
+ data = ef->data;
+ loop_data = ef->loop_data;
+ type = e->type;
+ event = e->event;
+
+ _ecore_unlock();
+ r = func_filter(data, loop_data, type, event);
+ _ecore_lock();
+ if (!r)
{
ecore_event_del(e);
}
event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
}
if (ef->func_end)
- ef->func_end(ef->data, ef->loop_data);
+ {
+ Ecore_End_Cb func_end;
+ void *loop_data;
+ void *data;
+
+ func_end = ef->func_end;
+ data = ef->data;
+ loop_data = ef->loop_data;
+
+ _ecore_unlock();
+ ef->func_end(ef->data, ef->loop_data);
+ _ecore_lock();
+ }
ef->references--;
}
eh = event_handler_current;
if (!eh->delete_me)
{
+ Ecore_Event_Handler_Cb func;
+ void *data;
+ int type;
+ void *event;
Eina_Bool ret;
handle_count++;
+ func = eh->func;
+ data = eh->data;
+ type = e->type;
+ event = e->event;
eh->references++;
- ret = eh->func(eh->data, e->type, e->event);
+ _ecore_unlock();
+ ret = func(data, type, event);
+ _ecore_lock();
eh->references--;
if (!ret)
static Ecore_Idle_Enterer *idle_enterer_current = NULL;
static int idle_enterers_delete_me = 0;
+static void *
+_ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer);
+
/**
* @addtogroup Ecore_Group Ecore - Main Loop and Job Functions.
*
EAPI Ecore_Idle_Enterer *
ecore_idle_enterer_add(Ecore_Task_Cb func, const void *data)
{
- Ecore_Idle_Enterer *ie;
+ Ecore_Idle_Enterer *ie = NULL;
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
- if (!func) return NULL;
+ if (!func) goto unlock;
ie = calloc(1, sizeof(Ecore_Idle_Enterer));
- if (!ie) return NULL;
+ if (!ie) goto unlock;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
ie->func = func;
ie->data = (void *)data;
idle_enterers = (Ecore_Idle_Enterer *) eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
+unlock:
+ _ecore_unlock();
return ie;
}
EAPI Ecore_Idle_Enterer *
ecore_idle_enterer_before_add(Ecore_Task_Cb func, const void *data)
{
- Ecore_Idle_Enterer *ie;
+ Ecore_Idle_Enterer *ie = NULL;
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
- if (!func) return NULL;
+ if (!func) goto unlock;
ie = calloc(1, sizeof(Ecore_Idle_Enterer));
- if (!ie) return NULL;
+ if (!ie) goto unlock;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
ie->func = func;
ie->data = (void *)data;
idle_enterers = (Ecore_Idle_Enterer *) eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
+unlock:
+ _ecore_unlock();
return ie;
}
EAPI void *
ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
{
- ECORE_MAIN_LOOP_ASSERT();
+ void *data;
if (!ECORE_MAGIC_CHECK(idle_enterer, ECORE_MAGIC_IDLE_ENTERER))
{
"ecore_idle_enterer_del");
return NULL;
}
- EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_enterer->delete_me, NULL);
- idle_enterer->delete_me = 1;
- idle_enterers_delete_me = 1;
- return idle_enterer->data;
+ _ecore_lock();
+ data = _ecore_idle_enterer_del(idle_enterer);
+ _ecore_unlock();
+ return data;
}
/**
* @}
*/
+static void *
+_ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
+{
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_enterer->delete_me, NULL);
+ idle_enterer->delete_me = 1;
+ idle_enterers_delete_me = 1;
+ return idle_enterer->data;
+}
+
+
void
_ecore_idle_enterer_shutdown(void)
{
Ecore_Idle_Enterer *ie = (Ecore_Idle_Enterer *)idle_enterer_current;
if (!ie->delete_me)
{
+ Ecore_Task_Cb func;
+ void *data;
+ Eina_Bool ret;
+
+ func = ie->func;
+ data = ie->data;
ie->references++;
- if (!ie->func(ie->data))
+ _ecore_unlock();
+ ret = func(data);
+ _ecore_lock();
+ if (!ret)
{
- if (!ie->delete_me) ecore_idle_enterer_del(ie);
+ if (!ie->delete_me) _ecore_idle_enterer_del(ie);
}
ie->references--;
}
static Ecore_Idle_Exiter *idle_exiter_current = NULL;
static int idle_exiters_delete_me = 0;
+static void *
+_ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter);
+
/**
* @addtogroup Ecore_Group Ecore - Main Loop and Job Functions.
*
EAPI Ecore_Idle_Exiter *
ecore_idle_exiter_add(Ecore_Task_Cb func, const void *data)
{
- Ecore_Idle_Exiter *ie;
+ Ecore_Idle_Exiter *ie = NULL;
- ECORE_MAIN_LOOP_ASSERT();
-
- if (!func) return NULL;
+ _ecore_lock();
+ if (!func) goto unlock;
ie = calloc(1, sizeof(Ecore_Idle_Exiter));
- if (!ie) return NULL;
+ if (!ie) goto unlock;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_EXITER);
ie->func = func;
ie->data = (void *)data;
idle_exiters = (Ecore_Idle_Exiter *) eina_inlist_append(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
+unlock:
+ _ecore_unlock();
return ie;
}
EAPI void *
ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter)
{
- ECORE_MAIN_LOOP_ASSERT();
+ void *data;
if (!ECORE_MAGIC_CHECK(idle_exiter, ECORE_MAGIC_IDLE_EXITER))
{
"ecore_idle_exiter_del");
return NULL;
}
- EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_exiter->delete_me, NULL);
- idle_exiter->delete_me = 1;
- idle_exiters_delete_me = 1;
- return idle_exiter->data;
+ _ecore_lock();
+ data = _ecore_idle_exiter_del(idle_exiter);
+ _ecore_unlock();
+ return data;
}
/**
* @}
*/
+static void *
+_ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter)
+{
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_exiter->delete_me, NULL);
+ idle_exiter->delete_me = 1;
+ idle_exiters_delete_me = 1;
+ return idle_exiter->data;
+}
+
void
_ecore_idle_exiter_shutdown(void)
{
Ecore_Idle_Exiter *ie = (Ecore_Idle_Exiter *)idle_exiter_current;
if (!ie->delete_me)
{
+ Ecore_Task_Cb func;
+ void *data;
+ Eina_Bool ret;
+
+ func = ie->func;
+ data = ie->data;
ie->references++;
- if (!ie->func(ie->data))
+ _ecore_unlock();
+ ret = func(data);
+ _ecore_lock();
+ if (!ret)
{
- if (!ie->delete_me) ecore_idle_exiter_del(ie);
+ if (!ie->delete_me) _ecore_idle_exiter_del(ie);
}
ie->references--;
}
static Ecore_Idler *idler_current = NULL;
static int idlers_delete_me = 0;
+static void *
+_ecore_idler_del(Ecore_Idler *idler);
+
/**
* @addtogroup Ecore_Group Ecore - Main Loop and Job Functions.
*
EAPI Ecore_Idler *
ecore_idler_add(Ecore_Task_Cb func, const void *data)
{
- Ecore_Idler *ie;
+ Ecore_Idler *ie = NULL;
- if (!func) return NULL;
+ _ecore_lock();
+ if (!func) goto unlock;
ie = calloc(1, sizeof(Ecore_Idler));
- if (!ie) return NULL;
+ if (!ie) goto unlock;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLER);
ie->func = func;
ie->data = (void *)data;
idlers = (Ecore_Idler *) eina_inlist_append(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
+unlock:
+ _ecore_unlock();
return ie;
}
EAPI void *
ecore_idler_del(Ecore_Idler *idler)
{
+ void *data = NULL;
+
if (!ECORE_MAGIC_CHECK(idler, ECORE_MAGIC_IDLER))
{
ECORE_MAGIC_FAIL(idler, ECORE_MAGIC_IDLER,
"ecore_idler_del");
return NULL;
}
- EINA_SAFETY_ON_TRUE_RETURN_VAL(idler->delete_me, NULL);
- idler->delete_me = 1;
- idlers_delete_me = 1;
- return idler->data;
+
+ _ecore_lock();
+ data = _ecore_idler_del(idler);
+ _ecore_unlock();
+ return data;
}
/**
* @}
*/
+static void *
+_ecore_idler_del(Ecore_Idler *idler)
+{
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(idler->delete_me, NULL);
+ idler->delete_me = 1;
+ idlers_delete_me = 1;
+ return idler->data;
+}
+
+
void
_ecore_idler_shutdown(void)
{
Ecore_Idler *ie = (Ecore_Idler *)idler_current;
if (!ie->delete_me)
{
+ Eina_Bool ret;
+ Ecore_Task_Cb func;
+ void *data;
+
+ func = ie->func;
+ data = ie->data;
ie->references++;
- if (!ie->func(ie->data))
+ _ecore_unlock();
+ ret = func(data);
+ _ecore_lock();
+ if (!ret)
{
- if (!ie->delete_me) ecore_idler_del(ie);
+ if (!ie->delete_me) _ecore_idler_del(ie);
}
ie->references--;
}
{
gboolean ready = FALSE;
+ _ecore_lock();
in_main_loop++;
if (!ecore_idling && !_ecore_glib_idle_enterer_called)
in_main_loop--;
INF("leave, timeout = %d", *next_time);
+ _ecore_unlock();
/* ready if we're not running (about to quit) */
return ready;
{
gboolean ret = FALSE;
+ _ecore_lock();
in_main_loop++;
/* check if old timers expired */
ret = (0.0 == _ecore_timer_next_get());
in_main_loop--;
+ _ecore_unlock();
return ret;
}
gboolean events_ready, timers_ready, idlers_ready;
double next_time;
+ _ecore_lock();
_ecore_time_loop_time = ecore_time_get();
_ecore_timer_enable_new();
next_time = _ecore_timer_next_get();
}
in_main_loop--;
+ _ecore_unlock();
return TRUE; /* what should be returned here? */
}
EAPI void
ecore_main_loop_iterate(void)
{
- ECORE_MAIN_LOOP_ASSERT();
#ifndef USE_G_MAIN_LOOP
+ _ecore_lock();
_ecore_main_loop_iterate_internal(1);
+ _ecore_unlock();
#else
g_main_context_iteration(NULL, 1);
#endif
EAPI void
ecore_main_loop_begin(void)
{
- ECORE_MAIN_LOOP_ASSERT();
#ifndef USE_G_MAIN_LOOP
+ _ecore_lock();
in_main_loop++;
while (do_quit == 0) _ecore_main_loop_iterate_internal(0);
do_quit = 0;
in_main_loop--;
+ _ecore_unlock();
#else
ecore_main_loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(ecore_main_loop);
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)
{
- Ecore_Fd_Handler *fdh;
+ Ecore_Fd_Handler *fdh = NULL;
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
- if ((fd < 0) || (flags == 0) || (!func)) return NULL;
+ if ((fd < 0) || (flags == 0) || (!func)) goto unlock;
fdh = calloc(1, sizeof(Ecore_Fd_Handler));
if (!fdh) return NULL;
int err = errno;
ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err));
free(fdh);
- return NULL;
+ goto unlock;
}
fdh->read_active = EINA_FALSE;
fdh->write_active = EINA_FALSE;
fd_handlers = (Ecore_Fd_Handler *)
eina_inlist_append(EINA_INLIST_GET(fd_handlers),
EINA_INLIST_GET(fdh));
+unlock:
+ _ecore_unlock();
+
return fdh;
}
EAPI void *
ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
{
- ECORE_MAIN_LOOP_ASSERT();
+ void *ret = NULL;
+
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
{
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
"ecore_main_fd_handler_del");
- return NULL;
+ goto unlock;
}
if (fd_handler->delete_me)
{
ERR("fdh %p deleted twice", fd_handler);
- return NULL;
+ goto unlock;
}
_ecore_main_fdh_poll_del(fd_handler);
fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fd_handler);
if (fd_handler->buf_func && fd_handlers_with_buffer)
fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fd_handler);
- return fd_handler->data;
+ ret = fd_handler->data;
+unlock:
+ _ecore_unlock();
+ return ret;
}
#ifdef _WIN32
EAPI void
ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data)
{
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
{
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
"ecore_main_fd_handler_prepare_callback_set");
- return;
+ goto unlock;
}
fd_handler->prep_func = func;
fd_handler->prep_data = (void *)data;
(fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler))))
/* FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! */
fd_handlers_with_prep = eina_list_append(fd_handlers_with_prep, fd_handler);
+unlock:
+ _ecore_unlock();
}
/**
EAPI int
ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
{
+ int fd = -1;
+
+ _ecore_lock();
+
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
{
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
"ecore_main_fd_handler_fd_get");
- return -1;
+ goto unlock;
}
- return fd_handler->fd;
+ fd = fd_handler->fd;
+unlock:
+ _ecore_unlock();
+ return fd;
}
/**
{
int ret = EINA_FALSE;
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
{
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
"ecore_main_fd_handler_active_get");
- return EINA_FALSE;
+ goto unlock;
}
if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE;
if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE;
if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE;
+unlock:
+ _ecore_unlock();
return ret;
}
{
int ret;
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
{
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
"ecore_main_fd_handler_active_set");
- return;
+ goto unlock;
}
fd_handler->flags = flags;
ret = _ecore_main_fdh_poll_modify(fd_handler);
{
ERR("Failed to mod epoll fd %d: %s!", fd_handler->fd, strerror(ret));
}
+unlock:
+ _ecore_unlock();
}
/**
}
if (!fdh->delete_me && fdh->prep_func)
{
+ Ecore_Fd_Prep_Cb prep_func;
+ void *prep_data;
+
+ prep_func = fdh->prep_func;
+ prep_data = fdh->prep_data;
fdh->references++;
- fdh->prep_func(fdh->prep_data, fdh);
+ _ecore_unlock();
+ prep_func(prep_data, fdh);
+ _ecore_lock();
fdh->references--;
}
else
if (_ecore_signal_count_get()) return -1;
+ _ecore_unlock();
ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
+ _ecore_lock();
_ecore_time_loop_time = ecore_time_get();
if (ret < 0)
ERR("Found bad fd at index %d", fdh->fd);
if (fdh->flags & ECORE_FD_ERROR)
{
+ Eina_Bool ret;
ERR("Fd set for error! calling user");
fdh->references++;
- if (!fdh->func(fdh->data, fdh))
+ _ecore_unlock();
+ ret = fdh->func(fdh->data, fdh);
+ _ecore_lock();
+ if (!ret)
{
ERR("Fd function err returned 0, remove it");
if (!fdh->delete_me)
(fdh->write_active) ||
(fdh->error_active))
{
+ Eina_Bool ret;
fdh->references++;
- if (!fdh->func(fdh->data, fdh))
+ _ecore_unlock();
+ ret = fdh->func(fdh->data, fdh);
+ _ecore_lock();
+ if (!ret)
{
if (!fdh->delete_me)
{
}
if ((!fdh->delete_me) && fdh->buf_func)
{
+ Ecore_Fd_Cb buf_func;
+ void *buf_data;
+ Eina_Bool r;
+
+ /* copy data before releasing lock */
+ buf_func = fdh->buf_func;
+ buf_data = fdh->buf_data;
fdh->references++;
- if (fdh->buf_func(fdh->buf_data, fdh))
+ _ecore_unlock();
+ r = buf_func(buf_data, fdh);
+ _ecore_lock();
+ if (r)
{
- ret |= fdh->func(fdh->data, fdh);
+ Ecore_Fd_Cb func;
+ void *data;
+
+ func = fdh->func;
+ data = fdh->data;
+ _ecore_unlock();
+ ret |= func(data, fdh);
+ _ecore_lock();
fdh->read_active = EINA_TRUE;
_ecore_try_add_to_call_list(fdh);
}
void _ecore_time_init(void);
+Ecore_Timer *_ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data);
+void *_ecore_timer_del(Ecore_Timer *timer);
+void _ecore_timer_delay(Ecore_Timer *timer, double add);
void _ecore_timer_shutdown(void);
void _ecore_timer_cleanup(void);
void _ecore_timer_enable_new(void);
void _ecore_throttle(void);
+#ifdef HAVE_THREAD_SAFETY
+void _ecore_lock(void);
+void _ecore_unlock(void);
+#else
+static inline void _ecore_lock(void)
+ {
+ /* at least check we're not being called from a thread */
+ ECORE_MAIN_LOOP_ASSERT();
+ }
+
+static inline void _ecore_unlock(void)
+ {
+ }
+#endif
+
extern int _ecore_fps_debug;
extern double _ecore_time_loop_time;
extern Eina_Bool _ecore_glib_always_integrate;
if ((n < MAXSIGQ) && (sigusr1_info[n].si_signo))
e->data = sigusr1_info[n];
- ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
+ _ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
}
sig_count--;
}
if ((n < MAXSIGQ) && (sigusr2_info[n].si_signo))
e->data = sigusr2_info[n];
- ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
+ _ecore_event_add(ECORE_EVENT_SIGNAL_USER, e, NULL, NULL);
}
sig_count--;
}
if ((n < MAXSIGQ) && (sighup_info[n].si_signo))
e->data = sighup_info[n];
- ecore_event_add(ECORE_EVENT_SIGNAL_HUP, e, NULL, NULL);
+ _ecore_event_add(ECORE_EVENT_SIGNAL_HUP, e, NULL, NULL);
}
sig_count--;
}
if ((n < MAXSIGQ) && (sigquit_info[n].si_signo))
e->data = sigquit_info[n];
- ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
+ _ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
}
sig_count--;
}
if ((n < MAXSIGQ) && (sigint_info[n].si_signo))
e->data = sigint_info[n];
- ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
+ _ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
}
sig_count--;
}
if ((n < MAXSIGQ) && (sigterm_info[n].si_signo))
e->data = sigterm_info[n];
- ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
+ _ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, e, NULL, NULL);
}
sig_count--;
}
if ((n < MAXSIGQ) && (sigpwr_info[n].si_signo))
e->data = sigpwr_info[n];
- ecore_event_add(ECORE_EVENT_SIGNAL_POWER, e, NULL, NULL);
+ _ecore_event_add(ECORE_EVENT_SIGNAL_POWER, e, NULL, NULL);
}
sig_count--;
}
#endif
#include <sys/time.h>
+#include <assert.h>
#ifdef HAVE_EVIL
# include <Evil.h>
static LK(_ecore_thread_global_hash_mutex);
static CD(_ecore_thread_global_hash_cond);
+static LK(_ecore_main_loop_mutex);
static Eina_Bool have_main_loop_thread = 0;
static Eina_Trash *_ecore_thread_worker_trash = NULL;
LKI(_ecore_pending_job_threads_mutex);
LRWKI(_ecore_thread_global_hash_lock);
LKI(_ecore_thread_global_hash_mutex);
+ LKI(_ecore_main_loop_mutex);
CDI(_ecore_thread_global_hash_cond);
#endif
}
}
}
+#ifdef HAVE_THREAD_SAFETY
+static int lock_count;
+
+void
+_ecore_lock(void)
+{
+ LKL(_ecore_main_loop_mutex);
+ lock_count++;
+ assert(lock_count == 1);
+}
+
+void
+_ecore_unlock(void)
+{
+ lock_count--;
+ assert(lock_count == 0);
+ LKU(_ecore_main_loop_mutex);
+}
+#endif
+
EAPI Ecore_Thread *
ecore_thread_run(Ecore_Thread_Cb func_blocking,
Ecore_Thread_Cb func_end,
EAPI void
ecore_timer_precision_set(double value)
{
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
if (value < 0.0)
{
ERR("Precision %f less than zero, ignored", value);
- return;
+ goto unlock;
}
precision = value;
+
+unlock:
+ _ecore_unlock();
}
/**
ecore_timer_add(double in, Ecore_Task_Cb func, const void *data)
{
double now;
- Ecore_Timer *timer;
+ Ecore_Timer *timer = NULL;
- ECORE_MAIN_LOOP_ASSERT();
-
- if (!func) return NULL;
+ _ecore_lock();
+ if (!func) goto unlock;
if (in < 0.0) in = 0.0;
timer = calloc(1, sizeof(Ecore_Timer));
- if (!timer) return NULL;
+ if (!timer) goto unlock;
ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER);
now = ecore_time_get();
#endif
_ecore_timer_set(timer, now + in, in, func, (void *)data);
+unlock:
+ _ecore_unlock();
return timer;
}
EAPI Ecore_Timer *
ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data)
{
- double now;
Ecore_Timer *timer;
- ECORE_MAIN_LOOP_ASSERT();
-
- if (!func) return NULL;
- if (in < 0.0) in = 0.0;
- timer = calloc(1, sizeof(Ecore_Timer));
- if (!timer) return NULL;
- ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER);
- now = ecore_loop_time_get();
-
-#ifdef WANT_ECORE_TIMER_DUMP
- timer->timer_bt_num = backtrace((void**) (timer->timer_bt),
- ECORE_TIMER_DEBUG_BT_NUM);
-#endif
+ _ecore_lock();
+ timer = _ecore_timer_loop_add(in, func, data);
+ _ecore_unlock();
- _ecore_timer_set(timer, now + in, in, func, (void *)data);
return timer;
}
EAPI void *
ecore_timer_del(Ecore_Timer *timer)
{
- ECORE_MAIN_LOOP_ASSERT();
+ void *data = NULL;
+
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
{
ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
"ecore_timer_del");
- return NULL;
+ goto unlock;
}
- if (timer->frozen && !timer->references)
- {
- void *data = timer->data;
-
- suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
-
- if (timer->delete_me)
- timers_delete_me--;
-
- free(timer);
- return data;
- }
+ data = _ecore_timer_del(timer);
- EINA_SAFETY_ON_TRUE_RETURN_VAL(timer->delete_me, NULL);
- timer->delete_me = 1;
- timers_delete_me++;
- return timer->data;
+unlock:
+ _ecore_unlock();
+ return data;
}
/**
EAPI void
ecore_timer_interval_set(Ecore_Timer *timer, double in)
{
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
{
ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
"ecore_timer_interval_set");
- return;
+ goto unlock;
}
timer->in = in;
+unlock:
+ _ecore_unlock();
}
/**
EAPI double
ecore_timer_interval_get(Ecore_Timer *timer)
{
- ECORE_MAIN_LOOP_ASSERT();
+ double interval;
+
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
{
ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
"ecore_timer_interval_get");
- return -1.0;
+ interval = -1.0;
+ goto unlock;
}
- return timer->in;
+ interval = timer->in;
+unlock:
+ _ecore_unlock();
+ return interval;
}
/**
EAPI void
ecore_timer_delay(Ecore_Timer *timer, double add)
{
- ECORE_MAIN_LOOP_ASSERT();
-
if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
{
ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
return;
}
- if (timer->frozen)
- {
- timer->pending += add;
- }
- else
- {
- timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
- _ecore_timer_set(timer, timer->at + add, timer->in, timer->func, timer->data);
- }
+ _ecore_lock();
+ _ecore_timer_delay(timer, add);
+ _ecore_unlock();
}
/**
ecore_timer_pending_get(Ecore_Timer *timer)
{
double now;
+ double ret = 0.0;
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
{
ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
"ecore_timer_pending_get");
- return 0;
+ goto unlock;
}
now = ecore_time_get();
if (timer->frozen)
- return timer->pending;
- return timer->at - now;
+ ret = timer->pending;
+ else
+ ret = timer->at - now;
+unlock:
+ _ecore_unlock();
+ return ret;
}
/**
{
double now;
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
{
ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
"ecore_timer_freeze");
- return ;
+ goto unlock;
}
/* Timer already frozen */
if (timer->frozen)
- return ;
+ goto unlock;
timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
suspended = (Ecore_Timer *) eina_inlist_prepend(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
timer->pending = timer->at - now;
timer->at = 0.0;
timer->frozen = 1;
+unlock:
+ _ecore_unlock();
}
/**
{
double now;
- ECORE_MAIN_LOOP_ASSERT();
+ _ecore_lock();
if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
{
ECORE_MAGIC_FAIL(timer, ECORE_MAGIC_TIMER,
"ecore_timer_thaw");
- return ;
+ goto unlock;
}
/* Timer not frozen */
if (!timer->frozen)
- return ;
+ goto unlock;
suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
now = ecore_time_get();
_ecore_timer_set(timer, timer->pending + now, timer->in, timer->func, timer->data);
+unlock:
+ _ecore_unlock();
}
EAPI char *
int living_timer = 0;
int unknow_timer = 0;
+ _ecore_lock();
result = eina_strbuf_new();
EINA_INLIST_FOREACH(timers, tm)
out = eina_strbuf_string_steal(result);
eina_strbuf_free(result);
+ _ecore_unlock();
return out;
#else
* @}
*/
+Ecore_Timer *
+_ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data)
+{
+ double now;
+ Ecore_Timer *timer = NULL;
+
+ if (!func) return timer;
+ if (in < 0.0) in = 0.0;
+ timer = calloc(1, sizeof(Ecore_Timer));
+ if (!timer) return timer;
+ ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER);
+ now = ecore_loop_time_get();
+
+#ifdef WANT_ECORE_TIMER_DUMP
+ timer->timer_bt_num = backtrace((void**) (timer->timer_bt),
+ ECORE_TIMER_DEBUG_BT_NUM);
+#endif
+ _ecore_timer_set(timer, now + in, in, func, (void *)data);
+ return timer;
+}
+
+EAPI void
+_ecore_timer_delay(Ecore_Timer *timer, double add)
+{
+ if (timer->frozen)
+ {
+ timer->pending += add;
+ }
+ else
+ {
+ timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+ _ecore_timer_set(timer, timer->at + add, timer->in, timer->func, timer->data);
+ }
+}
+
+
+void *
+_ecore_timer_del(Ecore_Timer *timer)
+{
+ if (timer->frozen && !timer->references)
+ {
+ void *data = timer->data;
+
+ suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
+
+ if (timer->delete_me)
+ timers_delete_me--;
+
+ free(timer);
+ return data;
+ }
+
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(timer->delete_me, NULL);
+ timer->delete_me = 1;
+ timers_delete_me++;
+ return timer->data;
+}
+
void
_ecore_timer_shutdown(void)
{
_ecore_timer_set(timer, timer->at + timer->in, timer->in, timer->func, timer->data);
}
+/* assume that we hold the ecore lock when entering this function */
int
_ecore_timer_call(double when)
{
while (timer_current)
{
Ecore_Timer *timer = timer_current;
+ Eina_Bool cont;
+ Ecore_Task_Cb func;
+ void *data;
if (timer->at > when)
{
}
timer->references++;
- if (!timer->func(timer->data))
+ func = timer->func;
+ data = timer->data;
+ _ecore_unlock();
+ cont = func(data);
+ _ecore_lock();
+ if (!cont)
{
- if (!timer->delete_me) ecore_timer_del(timer);
+ if (!timer->delete_me) _ecore_timer_del(timer);
}
timer->references--;