ecore: cancel all pending thread at shutdown.

Hopefully this will fix bug #961.


SVN revision: 71526
This commit is contained in:
Cedric BAIL 2012-05-30 03:10:30 +00:00
parent 2c4c47ae0f
commit a5f658a4b2
3 changed files with 50 additions and 10 deletions

View File

@ -654,16 +654,16 @@
* Reduce race condition on Ecore_Thread shutdown. * Reduce race condition on Ecore_Thread shutdown.
2012-05-22 Carsten Haitzler (The Rasterman) 2012-05-22 Carsten Haitzler (The Rasterman)
* Add ecore_x_mouse_in_send() and ecore_x_mouse_out_send() * Add ecore_x_mouse_in_send() and ecore_x_mouse_out_send()
* Add ecore_x illume access control/action atoms+api's * Add ecore_x illume access control/action atoms+api's
2012-05-24 Doyoun Kang 2012-05-24 Doyoun Kang
* Add Ecore_X_Error_Code enumeration in ecore_x * Add Ecore_X_Error_Code enumeration in ecore_x
2012-05-24 Carsten Haitzler (The Rasterman) 2012-05-24 Carsten Haitzler (The Rasterman)
* Add ecore_con_client_ref() and ecore_con_client_unref() * Add ecore_con_client_ref() and ecore_con_client_unref()
* Fix ecore_con to obey reference counting for con clients * Fix ecore_con to obey reference counting for con clients
@ -676,16 +676,19 @@
so now have fairer scheduling. so now have fairer scheduling.
* Allow 16 * cpu num for worker threads (default still cpu num) * Allow 16 * cpu num for worker threads (default still cpu num)
2012-05-25 Carsten Haitzler (The Rasterman) 2012-05-25 Carsten Haitzler (The Rasterman)
* Fix ecore mainloop issue if you begin the mainloop, keep a * Fix ecore mainloop issue if you begin the mainloop, keep a
timer around, quit mainloop, then start it again expecting the timer timer around, quit mainloop, then start it again expecting the timer
to keep ticking off. also happens to be an issue with to keep ticking off. also happens to be an issue with
iterating the mainloop. iterating the mainloop.
2012-05-25 Rob Bradford 2012-05-25 Rob Bradford
* Make ecore_{software_x11, software_x11_8, software_x11_16, wayland, * Make ecore_{software_x11, software_x11_8, software_x11_16, wayland,
directfb}_window_get return 0 if the Ecore_Evas was not created with directfb}_window_get return 0 if the Ecore_Evas was not created with
the appropriate constructor. the appropriate constructor.
2012-05-30 Cedric Bail
* Force cancel of all running Ecore_Thread on shutdown.

View File

@ -15,6 +15,7 @@ Fixes:
- Reduce rounding error in ecore_animator_pos_map. - Reduce rounding error in ecore_animator_pos_map.
- Send mouse move event before mouse down event in ecore_extn - Send mouse move event before mouse down event in ecore_extn
- Reduce race condition on shutdown of Ecore_Thread. - Reduce race condition on shutdown of Ecore_Thread.
- Force cancel of all running Ecore_Thread on shutdown.
Ecore 1.2.0 Ecore 1.2.0

View File

@ -217,6 +217,7 @@ static void _ecore_thread_handler(void *data);
static int _ecore_thread_count = 0; static int _ecore_thread_count = 0;
static Eina_List *_ecore_running_job = NULL;
static Eina_List *_ecore_pending_job_threads = NULL; static Eina_List *_ecore_pending_job_threads = NULL;
static Eina_List *_ecore_pending_job_threads_feedback = NULL; static Eina_List *_ecore_pending_job_threads_feedback = NULL;
static LK(_ecore_pending_job_threads_mutex); static LK(_ecore_pending_job_threads_mutex);
@ -412,7 +413,7 @@ _ecore_short_job(PH(thread))
work = eina_list_data_get(_ecore_pending_job_threads); work = eina_list_data_get(_ecore_pending_job_threads);
_ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads, _ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads,
_ecore_pending_job_threads); _ecore_pending_job_threads);
_ecore_running_job = eina_list_append(_ecore_running_job, work);
LKU(_ecore_pending_job_threads_mutex); LKU(_ecore_pending_job_threads_mutex);
LKL(work->cancel_mutex); LKL(work->cancel_mutex);
@ -421,6 +422,10 @@ _ecore_short_job(PH(thread))
work->self = thread; work->self = thread;
if (!cancel) if (!cancel)
work->u.short_run.func_blocking((void *) work->data, (Ecore_Thread*) work); work->u.short_run.func_blocking((void *) work->data, (Ecore_Thread*) work);
LKL(_ecore_pending_job_threads_mutex);
_ecore_running_job = eina_list_remove(_ecore_running_job, work);
LKU(_ecore_pending_job_threads_mutex);
if (work->reschedule) if (work->reschedule)
{ {
@ -453,7 +458,7 @@ _ecore_feedback_job(PH(thread))
work = eina_list_data_get(_ecore_pending_job_threads_feedback); work = eina_list_data_get(_ecore_pending_job_threads_feedback);
_ecore_pending_job_threads_feedback = eina_list_remove_list(_ecore_pending_job_threads_feedback, _ecore_pending_job_threads_feedback = eina_list_remove_list(_ecore_pending_job_threads_feedback,
_ecore_pending_job_threads_feedback); _ecore_pending_job_threads_feedback);
_ecore_running_job = eina_list_append(_ecore_running_job, work);
LKU(_ecore_pending_job_threads_mutex); LKU(_ecore_pending_job_threads_mutex);
LKL(work->cancel_mutex); LKL(work->cancel_mutex);
@ -462,7 +467,11 @@ _ecore_feedback_job(PH(thread))
work->self = thread; work->self = thread;
if (!cancel) if (!cancel)
work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work); work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work);
LKL(_ecore_pending_job_threads_mutex);
_ecore_running_job = eina_list_remove(_ecore_running_job, work);
LKU(_ecore_pending_job_threads_mutex);
if (work->reschedule) if (work->reschedule)
{ {
work->reschedule = EINA_FALSE; work->reschedule = EINA_FALSE;
@ -539,10 +548,10 @@ restart:
goto restart; goto restart;
} }
_ecore_thread_count--; _ecore_thread_count--;
LKU(_ecore_pending_job_threads_mutex);
ecore_main_loop_thread_safe_call_async((Ecore_Cb) _ecore_thread_join, ecore_main_loop_thread_safe_call_async((Ecore_Cb) _ecore_thread_join,
(void*) PHS()); (void*) PHS());
LKU(_ecore_pending_job_threads_mutex);
return NULL; return NULL;
} }
@ -591,6 +600,9 @@ _ecore_thread_shutdown(void)
/* FIXME: If function are still running in the background, should we kill them ? */ /* FIXME: If function are still running in the background, should we kill them ? */
#ifdef EFL_HAVE_THREADS #ifdef EFL_HAVE_THREADS
Ecore_Pthread_Worker *work; Ecore_Pthread_Worker *work;
Eina_List *l;
Eina_Bool test;
int iteration = 0;
LKL(_ecore_pending_job_threads_mutex); LKL(_ecore_pending_job_threads_mutex);
@ -608,9 +620,33 @@ _ecore_thread_shutdown(void)
free(work); free(work);
} }
EINA_LIST_FOREACH(_ecore_running_job, l, work)
ecore_thread_cancel((Ecore_Thread*) work);
LKU(_ecore_pending_job_threads_mutex); LKU(_ecore_pending_job_threads_mutex);
/* FIXME: Improve emergency shutdown, now that we use async call, we can do something */ do
{
LKL(_ecore_pending_job_threads_mutex);
if (_ecore_thread_count > 0)
{
test = EINA_TRUE;
}
else
{
test = EINA_FALSE;
}
LKU(_ecore_pending_job_threads_mutex);
iteration++;
if (test) usleep(50000);
}
while (test == EINA_TRUE && iteration < 20);
if (iteration == 20 && _ecore_thread_count > 0)
{
ERR("%i of the child thread are still running after 1s. This can lead to a segv. Sorry.", _ecore_thread_count);
}
if (_ecore_thread_global_hash) if (_ecore_thread_global_hash)
eina_hash_free(_ecore_thread_global_hash); eina_hash_free(_ecore_thread_global_hash);
have_main_loop_thread = 0; have_main_loop_thread = 0;