static Eina_Bool _ecore_idle_enterer_add(Ecore_Idle_Enterer *obj, Ecore_Idle_Enterer_Data *ie, Ecore_Task_Cb func, const void *data) { if (EINA_UNLIKELY(!eina_main_loop_is())) { eo_error_set(obj); EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); } ie->obj = obj; eo_do_super(obj, MY_CLASS, eo_constructor()); eo_manual_free_set(obj, EINA_TRUE); if (!func) { eo_error_set(obj); ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); return EINA_FALSE; } ie->func = func; ie->data = (void *)data; return EINA_TRUE; }
static Eina_Bool _ecore_timer_add(Ecore_Timer *obj, Ecore_Timer_Private_Data *timer, double now, double in, Ecore_Task_Cb func, const void *data) { if (EINA_UNLIKELY(!eina_main_loop_is())) { eo_error_set(obj); EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); } timer->obj = obj; eo_do_super(obj, eo_constructor()); eo_manual_free_set(obj, EINA_TRUE); if (!func) { eo_error_set(obj); ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); return EINA_FALSE; } if (in < 0.0) in = 0.0; #ifdef WANT_ECORE_TIMER_DUMP timer->timer_bt_num = backtrace((void **)(timer->timer_bt), ECORE_TIMER_DEBUG_BT_NUM); #endif _ecore_timer_set(obj, now + in, in, func, (void *)data); return EINA_TRUE; }
EAPI Eina_Error eina_error_get(void) { if (eina_main_loop_is()) return _eina_last_error; return (Eina_Error)(uintptr_t) eina_tls_get(_eina_last_key); }
EAPI void eina_error_set(Eina_Error err) { if (eina_main_loop_is()) _eina_last_error = err; else eina_tls_set(_eina_last_key, (void*)(uintptr_t) err); }
EOLIAN static void _ecore_idler_constructor(Eo *obj, Ecore_Idler_Data *ie, Ecore_Task_Cb func, const void *data) { if (EINA_UNLIKELY(!eina_main_loop_is())) { EINA_MAIN_LOOP_CHECK_RETURN; } ie->obj = obj; eo_manual_free_set(obj, EINA_TRUE); if (!func) { ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME); return; } ie->func = func; ie->data = (void *)data; idlers = (Ecore_Idler_Data *)eina_inlist_append(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie)); }
EAPI void * ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback, void *data) { Ecore_Safe_Call *order; void *ret; if (!callback) return NULL; if (eina_main_loop_is()) { return callback(data); } order = malloc(sizeof (Ecore_Safe_Call)); if (!order) return NULL; order->cb.sync = callback; order->data = data; eina_lock_new(&order->m); eina_condition_new(&order->c, &order->m); order->sync = EINA_TRUE; order->suspend = EINA_FALSE; _ecore_main_loop_thread_safe_call(order); eina_lock_take(&order->m); eina_condition_wait(&order->c); eina_lock_release(&order->m); ret = order->data; order->sync = EINA_FALSE; order->cb.async = _thread_safe_cleanup; order->data = order; _ecore_main_loop_thread_safe_call(order); return ret; }
EAPI int ecore_thread_main_loop_begin(void) { Ecore_Safe_Call *order; if (eina_main_loop_is()) { return ++_thread_loop; } order = malloc(sizeof (Ecore_Safe_Call)); if (!order) return -1; eina_lock_take(&_thread_id_lock); order->current_id = ++_thread_id_max; if (order->current_id < 0) { _thread_id_max = 0; order->current_id = ++_thread_id_max; } eina_lock_release(&_thread_id_lock); eina_lock_new(&order->m); eina_condition_new(&order->c, &order->m); order->suspend = EINA_TRUE; _ecore_main_loop_thread_safe_call(order); eina_lock_take(&order->m); while (order->current_id != _thread_id) eina_condition_wait(&order->c); eina_lock_release(&order->m); eina_main_loop_define(); _thread_loop = 1; return EINA_TRUE; }
EAPI int ecore_thread_main_loop_end(void) { int current_id; if (_thread_loop == 0) { ERR("the main loop is not locked ! No matching call to ecore_thread_main_loop_begin()."); return -1; } /* until we unlock the main loop, this thread has the main loop id */ if (!eina_main_loop_is()) { ERR("Not in a locked thread !"); return -1; } _thread_loop--; if (_thread_loop > 0) return _thread_loop; current_id = _thread_id; eina_lock_take(&_thread_mutex); _thread_id_update = _thread_id; eina_condition_broadcast(&_thread_cond); eina_lock_release(&_thread_mutex); eina_lock_take(&_thread_feedback_mutex); while (current_id == _thread_id && _thread_id != -1) eina_condition_wait(&_thread_feedback_cond); eina_lock_release(&_thread_feedback_mutex); return 0; }
EAPI void ecore_main_loop_thread_safe_call_async(Ecore_Cb callback, void *data) { Ecore_Safe_Call *order; if (!callback) return; if (eina_main_loop_is()) { callback(data); return; } order = malloc(sizeof (Ecore_Safe_Call)); if (!order) return; order->cb.async = callback; order->data = data; order->sync = EINA_FALSE; order->suspend = EINA_FALSE; _ecore_main_loop_thread_safe_call(order); }