From 6d2b2f366fc5161ac57be95d471d7e683a865073 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Wed, 30 May 2012 12:14:34 +0000 Subject: [PATCH] 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 --- legacy/ecore/ChangeLog | 1 + legacy/ecore/NEWS | 1 + legacy/ecore/src/lib/ecore/ecore.c | 14 ++++++--- legacy/ecore/src/lib/ecore/ecore_private.h | 2 ++ legacy/ecore/src/lib/ecore/ecore_thread.c | 34 ++++++++++++++++++---- 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/legacy/ecore/ChangeLog b/legacy/ecore/ChangeLog index ec93cb57aa..ed2826b2d3 100644 --- a/legacy/ecore/ChangeLog +++ b/legacy/ecore/ChangeLog @@ -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 diff --git a/legacy/ecore/NEWS b/legacy/ecore/NEWS index 1fa6a416e7..0aeebdc825 100644 --- a/legacy/ecore/NEWS +++ b/legacy/ecore/NEWS @@ -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 diff --git a/legacy/ecore/src/lib/ecore/ecore.c b/legacy/ecore/src/lib/ecore/ecore.c index 5dfe3d6fa0..7a221e3b52 100644 --- a/legacy/ecore/src/lib/ecore/ecore.c +++ b/legacy/ecore/src/lib/ecore/ecore.c @@ -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(); +} + diff --git a/legacy/ecore/src/lib/ecore/ecore_private.h b/legacy/ecore/src/lib/ecore/ecore_private.h index a35d12e5ab..d812e3a349 100644 --- a/legacy/ecore/src/lib/ecore/ecore_private.h +++ b/legacy/ecore/src/lib/ecore/ecore_private.h @@ -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; diff --git a/legacy/ecore/src/lib/ecore/ecore_thread.c b/legacy/ecore/src/lib/ecore/ecore_thread.c index 407e84bd0f..e2c491409f 100644 --- a/legacy/ecore/src/lib/ecore/ecore_thread.c +++ b/legacy/ecore/src/lib/ecore/ecore_thread.c @@ -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();