forked from enlightenment/efl
ecore: add ecore_main_loop_thread_safe_call.
NOTE: that's for you mike. SVN revision: 61857
This commit is contained in:
parent
0d7d7d8f06
commit
b4338b1c7f
|
@ -269,3 +269,7 @@
|
||||||
* Fix timer precision handling for grouping timer ticks so
|
* Fix timer precision handling for grouping timer ticks so
|
||||||
they actually do tick off together
|
they actually do tick off together
|
||||||
|
|
||||||
|
2011-07-28 Cedric Bail
|
||||||
|
|
||||||
|
* Add ecore_main_loop_thread_safe_call.
|
||||||
|
|
||||||
|
|
|
@ -736,6 +736,22 @@ extern "C" {
|
||||||
EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, Ecore_Win32_Handle_Cb func, const void *data);
|
EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, Ecore_Win32_Handle_Cb func, const void *data);
|
||||||
EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler);
|
EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Call callback in the main loop.
|
||||||
|
*
|
||||||
|
* @param callback The callback to call in the main loop
|
||||||
|
* @param data The data to give to that call back
|
||||||
|
*
|
||||||
|
* For all call that need to happen in the main loop (most EFL functions do),
|
||||||
|
* this helper function provide the infrastructure needed to do it safely
|
||||||
|
* by avoind dead lock, race condition and properly wake up the main loop.
|
||||||
|
*
|
||||||
|
* Remember after that function call, you should never touch again the @p data
|
||||||
|
* in the thread, it is owned by the main loop and you callback should take
|
||||||
|
* care of freeing it if necessary.
|
||||||
|
*/
|
||||||
|
EAPI void ecore_main_loop_thread_safe_call(Ecore_Cb callback, void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -53,6 +53,17 @@ static int _ecore_init_count = 0;
|
||||||
int _ecore_log_dom = -1;
|
int _ecore_log_dom = -1;
|
||||||
int _ecore_fps_debug = 0;
|
int _ecore_fps_debug = 0;
|
||||||
|
|
||||||
|
typedef struct _Ecore_Safe_Call Ecore_Safe_Call;
|
||||||
|
struct _Ecore_Safe_Call
|
||||||
|
{
|
||||||
|
Ecore_Cb cb;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void _thread_callback(void *data, void *buffer, unsigned int nbyte);
|
||||||
|
static Ecore_Pipe *_thread_call = NULL;
|
||||||
|
static Eina_Lock _thread_safety;
|
||||||
|
|
||||||
/** OpenBSD does not define CODESET
|
/** OpenBSD does not define CODESET
|
||||||
* FIXME ??
|
* FIXME ??
|
||||||
*/
|
*/
|
||||||
|
@ -126,6 +137,9 @@ ecore_init(void)
|
||||||
_ecore_job_init();
|
_ecore_job_init();
|
||||||
_ecore_time_init();
|
_ecore_time_init();
|
||||||
|
|
||||||
|
eina_lock_new(&_thread_safety);
|
||||||
|
_thread_call = ecore_pipe_add(_thread_callback, NULL);
|
||||||
|
|
||||||
#if HAVE_MALLINFO
|
#if HAVE_MALLINFO
|
||||||
if (getenv("ECORE_MEM_STAT"))
|
if (getenv("ECORE_MEM_STAT"))
|
||||||
{
|
{
|
||||||
|
@ -165,6 +179,9 @@ ecore_shutdown(void)
|
||||||
if (--_ecore_init_count != 0)
|
if (--_ecore_init_count != 0)
|
||||||
return _ecore_init_count;
|
return _ecore_init_count;
|
||||||
|
|
||||||
|
ecore_pipe_del(_thread_call);
|
||||||
|
eina_lock_free(&_thread_safety);
|
||||||
|
|
||||||
if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
|
if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
|
||||||
_ecore_poller_shutdown();
|
_ecore_poller_shutdown();
|
||||||
_ecore_animator_shutdown();
|
_ecore_animator_shutdown();
|
||||||
|
@ -203,6 +220,22 @@ ecore_shutdown(void)
|
||||||
return _ecore_init_count;
|
return _ecore_init_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
ecore_main_loop_thread_safe_call(Ecore_Cb callback, void *data)
|
||||||
|
{
|
||||||
|
Ecore_Safe_Call *order;
|
||||||
|
|
||||||
|
order = malloc(sizeof (Ecore_Safe_Call));
|
||||||
|
if (!order) return ;
|
||||||
|
|
||||||
|
order->cb = callback;
|
||||||
|
order->data = data;
|
||||||
|
|
||||||
|
eina_lock_take(&_thread_safety);
|
||||||
|
ecore_pipe_write(_thread_call, &order, sizeof (Ecore_Safe_Call*));
|
||||||
|
eina_lock_release(&_thread_safety);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
@ -428,3 +461,18 @@ _ecore_memory_statistic(__UNUSED__ void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
_thread_callback(void *data __UNUSED__, void *buffer, unsigned int nbyte)
|
||||||
|
{
|
||||||
|
Ecore_Safe_Call *call = buffer;
|
||||||
|
|
||||||
|
while (nbyte >= sizeof (Ecore_Safe_Call*))
|
||||||
|
{
|
||||||
|
call->cb(call->data);
|
||||||
|
free(call);
|
||||||
|
|
||||||
|
call++;
|
||||||
|
nbyte -= sizeof (Ecore_Safe_Call*);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue