* 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 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
-2012-05-24 Carsten Haitzler (The Rasterman)
+2012-05-24 Carsten Haitzler (The Rasterman)
* Add ecore_con_client_ref() and ecore_con_client_unref()
* Fix ecore_con to obey reference counting for con clients
so now have fairer scheduling.
* 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
timer around, quit mainloop, then start it again expecting the timer
to keep ticking off. also happens to be an issue with
iterating the mainloop.
-2012-05-25 Rob Bradford
+2012-05-25 Rob Bradford
* Make ecore_{software_x11, software_x11_8, software_x11_16, wayland,
directfb}_window_get return 0 if the Ecore_Evas was not created with
the appropriate constructor.
+2012-05-30 Cedric Bail
+
+ * Force cancel of all running Ecore_Thread on shutdown.
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_feedback = NULL;
static LK(_ecore_pending_job_threads_mutex);
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);
-
+ _ecore_running_job = eina_list_append(_ecore_running_job, work);
LKU(_ecore_pending_job_threads_mutex);
LKL(work->cancel_mutex);
work->self = thread;
if (!cancel)
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)
{
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);
-
+ _ecore_running_job = eina_list_append(_ecore_running_job, work);
LKU(_ecore_pending_job_threads_mutex);
LKL(work->cancel_mutex);
work->self = thread;
if (!cancel)
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)
{
work->reschedule = EINA_FALSE;
goto restart;
}
_ecore_thread_count--;
- LKU(_ecore_pending_job_threads_mutex);
ecore_main_loop_thread_safe_call_async((Ecore_Cb) _ecore_thread_join,
(void*) PHS());
+ LKU(_ecore_pending_job_threads_mutex);
return NULL;
}
/* FIXME: If function are still running in the background, should we kill them ? */
#ifdef EFL_HAVE_THREADS
Ecore_Pthread_Worker *work;
+ Eina_List *l;
+ Eina_Bool test;
+ int iteration = 0;
LKL(_ecore_pending_job_threads_mutex);
free(work);
}
+ EINA_LIST_FOREACH(_ecore_running_job, l, work)
+ ecore_thread_cancel((Ecore_Thread*) work);
+
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)
eina_hash_free(_ecore_thread_global_hash);
have_main_loop_thread = 0;