ecore: force pthread_join even when main loop isn't running.

pthread_create can fail if to much pthread are pending. As pthread_join
is only called when the main loop can flush the async call list, there was
a possibility for edje_cc to run out of thread due to that. We know
force the flush of the async call list and so call pthread_join when
pthread_create fail.


SVN revision: 71555
This commit is contained in:
Cedric BAIL 2012-05-30 12:14:34 +00:00
parent 7772b28002
commit 6d2b2f366f
5 changed files with 42 additions and 10 deletions

View File

@ -692,6 +692,7 @@
2012-05-30 Cedric Bail
* Force cancel of all running Ecore_Thread on shutdown.
* Make Ecore_Thread work reliabily when main loop isn't running.
2012-05-30 Mariusz Grzegorczyk

View File

@ -16,6 +16,7 @@ Fixes:
- Send mouse move event before mouse down event in ecore_extn
- Reduce race condition on shutdown of Ecore_Thread.
- Force cancel of all running Ecore_Thread on shutdown.
- Make Ecore_Thread work reliably when called without a running main loop.
Ecore 1.2.0

View File

@ -709,10 +709,8 @@ _thread_safe_cleanup(void *data)
eina_lock_free(&call->m);
}
static void
_thread_callback(void *data __UNUSED__,
void *buffer __UNUSED__,
unsigned int nbyte __UNUSED__)
void
_ecore_main_call_flush(void)
{
Ecore_Safe_Call *call;
Eina_List *callback;
@ -762,3 +760,11 @@ _thread_callback(void *data __UNUSED__,
}
}
static void
_thread_callback(void *data __UNUSED__,
void *buffer __UNUSED__,
unsigned int nbyte __UNUSED__)
{
_ecore_main_call_flush();
}

View File

@ -224,6 +224,8 @@ void _ecore_main_loop_shutdown(void);
void _ecore_throttle(void);
void _ecore_main_call_flush(void);
extern int _ecore_main_lock_count;
extern Eina_Lock _ecore_main_loop_lock;

View File

@ -168,7 +168,7 @@ struct _Ecore_Pthread_Worker
const void *data;
volatile int cancel;
int cancel;
#ifdef EFL_HAVE_THREADS
LK(cancel_mutex);
@ -280,7 +280,7 @@ _ecore_thread_data_free(void *data)
static void
_ecore_thread_join(PH(thread))
{
PHJ(thread);
PHJ(thread);
}
static void
@ -674,6 +674,7 @@ ecore_thread_run(Ecore_Thread_Cb func_blocking,
const void *data)
{
Ecore_Pthread_Worker *work;
Eina_Bool tried = EINA_FALSE;
#ifdef EFL_HAVE_THREADS
PH(thread);
#endif
@ -721,17 +722,20 @@ ecore_thread_run(Ecore_Thread_Cb func_blocking,
LKL(_ecore_pending_job_threads_mutex);
retry:
if (PHC(thread, _ecore_thread_worker, NULL) == 0)
{
_ecore_thread_count++;
LKU(_ecore_pending_job_threads_mutex);
return (Ecore_Thread *)work;
}
LKU(_ecore_pending_job_threads_mutex);
if (!tried)
{
_ecore_main_call_flush();
tried = EINA_TRUE;
goto retry;
}
eina_threads_shutdown();
LKL(_ecore_pending_job_threads_mutex);
if (_ecore_thread_count == 0)
{
_ecore_pending_job_threads = eina_list_remove(_ecore_pending_job_threads, work);
@ -746,6 +750,9 @@ ecore_thread_run(Ecore_Thread_Cb func_blocking,
work = NULL;
}
LKU(_ecore_pending_job_threads_mutex);
eina_threads_shutdown();
return (Ecore_Thread *)work;
#else
/*
@ -882,6 +889,7 @@ ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
{
#ifdef EFL_HAVE_THREADS
Ecore_Pthread_Worker *worker;
Eina_Bool tried = EINA_FALSE;
PH(thread);
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
@ -918,8 +926,15 @@ ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
eina_threads_init();
retry_direct:
if (PHC(t, _ecore_direct_worker, worker) == 0)
return (Ecore_Thread *)worker;
if (!tried)
{
_ecore_main_call_flush();
tried = EINA_TRUE;
goto retry_direct;
}
if (worker->u.feedback_run.direct_worker)
{
@ -947,12 +962,19 @@ ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
eina_threads_init();
LKL(_ecore_pending_job_threads_mutex);
retry:
if (PHC(thread, _ecore_thread_worker, NULL) == 0)
{
_ecore_thread_count++;
LKU(_ecore_pending_job_threads_mutex);
return (Ecore_Thread *)worker;
}
if (!tried)
{
_ecore_main_call_flush();
tried = EINA_TRUE;
goto retry;
}
LKU(_ecore_pending_job_threads_mutex);
eina_threads_shutdown();