ecore: make ecore_thread_main_loop_begin/end() recursive.

SVN revision: 62687
This commit is contained in:
Cedric BAIL 2011-08-22 09:47:17 +00:00
parent 3184b6e863
commit 8c078b294c
2 changed files with 33 additions and 11 deletions

View File

@ -448,7 +448,8 @@ extern "C" {
* @brief This function suspend the main loop in a know state * @brief This function suspend the main loop in a know state
* @since 1.1.0 * @since 1.1.0
* *
* @result EINA_TRUE if the main loop was suspended correctly. * @result the number of time ecore_thread_main_loop_begin() has been called
* in this thread, if the main loop was suspended correctly. If not, it return @c -1.
* *
* This function suspend the main loop in a know state, this let you * This function suspend the main loop in a know state, this let you
* use any EFL call you want after it return. Be carefull, the main loop * use any EFL call you want after it return. Be carefull, the main loop
@ -461,16 +462,20 @@ extern "C" {
* We still advise you, when possible, to use ecore_main_loop_thread_safe_call_async() * We still advise you, when possible, to use ecore_main_loop_thread_safe_call_async()
* as it will not block the thread nor the main loop. * as it will not block the thread nor the main loop.
*/ */
EAPI Eina_Bool ecore_thread_main_loop_begin(void); EAPI int ecore_thread_main_loop_begin(void);
/** /**
* @brief Unlock the main loop. * @brief Unlock the main loop.
* @since 1.1.0 * @since 1.1.0
* *
* @result the number of time ecore_thread_main_loop_end() need to be called before
* the main loop is unlocked again. @c -1 will be returned if you are trying to unlock
* when there wasn't enough call to ecore_thread_main_loop_begin().
*
* After a call to ecore_thread_main_loop_begin(), you need to absolutly * After a call to ecore_thread_main_loop_begin(), you need to absolutly
* call ecore_thread_main_loop_end(), or you application will stay frozen. * call ecore_thread_main_loop_end(), or you application will stay frozen.
*/ */
EAPI void ecore_thread_main_loop_end(void); EAPI int ecore_thread_main_loop_end(void);
/** /**
* @} * @}

View File

@ -76,7 +76,7 @@ static Eina_List *_thread_cb = NULL;
static Ecore_Pipe *_thread_call = NULL; static Ecore_Pipe *_thread_call = NULL;
static Eina_Lock _thread_safety; static Eina_Lock _thread_safety;
static Eina_Bool _thread_loop = EINA_FALSE; static int _thread_loop = 0;
static Eina_Lock _thread_mutex; static Eina_Lock _thread_mutex;
static Eina_Condition _thread_cond; static Eina_Condition _thread_cond;
@ -319,16 +319,18 @@ ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback, void *data)
return ret; return ret;
} }
EAPI Eina_Bool EAPI int
ecore_thread_main_loop_begin(void) ecore_thread_main_loop_begin(void)
{ {
Ecore_Safe_Call *order; Ecore_Safe_Call *order;
if (eina_main_loop_is()) if (eina_main_loop_is())
return EINA_FALSE; {
return ++_thread_loop;
}
order = malloc(sizeof (Ecore_Safe_Call)); order = malloc(sizeof (Ecore_Safe_Call));
if (!order) return EINA_FALSE; if (!order) return -1;
eina_lock_new(&order->m); eina_lock_new(&order->m);
eina_condition_new(&order->c, &order->m); eina_condition_new(&order->c, &order->m);
@ -342,19 +344,34 @@ ecore_thread_main_loop_begin(void)
eina_main_loop_define(); eina_main_loop_define();
_thread_loop = EINA_TRUE; _thread_loop = 1;
return EINA_TRUE; return EINA_TRUE;
} }
EAPI void EAPI int
ecore_thread_main_loop_end(void) ecore_thread_main_loop_end(void)
{ {
if (!_thread_loop) return ; 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 */ /* until we unlock the main loop, this thread has the main loop id */
if (!eina_main_loop_is()) return ; if (!eina_main_loop_is())
{
ERR("Not in a locked thread !");
return -1;
}
_thread_loop--;
if (_thread_loop > 0)
return _thread_loop;
eina_condition_broadcast(&_thread_cond); eina_condition_broadcast(&_thread_cond);
return 0;
} }
EAPI void EAPI void