cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=34758ad4f5eb1f036990faa7bfe8b258d1d4f497
commit 34758ad4f5eb1f036990faa7bfe8b258d1d4f497 Author: Cedric BAIL <ced...@osg.samsung.com> Date: Mon Dec 5 16:57:46 2016 -0800 evas: switch to use Ecore_Thread instead of half done Evas thread infrastructure. --- src/lib/evas/cache/evas_preload.c | 199 ++++++++++---------------------------- 1 file changed, 51 insertions(+), 148 deletions(-) diff --git a/src/lib/evas/cache/evas_preload.c b/src/lib/evas/cache/evas_preload.c index ecd3464..cd299e6 100644 --- a/src/lib/evas/cache/evas_preload.c +++ b/src/lib/evas/cache/evas_preload.c @@ -11,135 +11,87 @@ #include "evas_private.h" #include "Evas.h" -static int _threads_max = 0; - -typedef struct _Evas_Preload_Pthread_Worker Evas_Preload_Pthread_Worker; -typedef struct _Evas_Preload_Pthread_Data Evas_Preload_Pthread_Data; +#include "Ecore.h" +typedef struct _Evas_Preload_Pthread Evas_Preload_Pthread; typedef void (*_evas_preload_pthread_func)(void *data); -struct _Evas_Preload_Pthread_Worker +struct _Evas_Preload_Pthread { EINA_INLIST; + Ecore_Thread *thread; + _evas_preload_pthread_func func_heavy; _evas_preload_pthread_func func_end; _evas_preload_pthread_func func_cancel; void *data; - Eina_Bool cancel : 1; -}; - -struct _Evas_Preload_Pthread_Data -{ - Eina_Thread thread; }; -static int _threads_count = 0; -static Evas_Preload_Pthread_Worker *_workers = NULL; - -static LK(_mutex); +static Eina_Inlist *works = NULL; static void -_evas_preload_thread_end(void *data) +_evas_preload_thread_work_free(Evas_Preload_Pthread *work) { - Evas_Preload_Pthread_Data *pth = data; - Evas_Preload_Pthread_Data *p = NULL; + works = eina_inlist_remove(works, EINA_INLIST_GET(work)); - if ((p = eina_thread_join(pth->thread))) free(p); - else return; - eina_threads_shutdown(); + free(work); } static void -_evas_preload_thread_done(void *target EINA_UNUSED, Evas_Callback_Type type EINA_UNUSED, void *event_info) +_evas_preload_thread_success(void *data, Ecore_Thread *thread EINA_UNUSED) { - Evas_Preload_Pthread_Worker *work = event_info; - if (work->cancel) - { - if (work->func_cancel) work->func_cancel(work->data); - } - else - work->func_end(work->data); + Evas_Preload_Pthread *work = data; - free(work); + work->func_end(work->data); + + _evas_preload_thread_work_free(work); } -static void * -_evas_preload_thread_worker(void *data, Eina_Thread thread EINA_UNUSED) +static void +_evas_preload_thread_fail(void *data, Ecore_Thread *thread EINA_UNUSED) { - Evas_Preload_Pthread_Data *pth = data; - Evas_Preload_Pthread_Worker *work; - - eina_thread_name_set(eina_thread_self(), "Eevas-preload"); -on_error: - for (;;) - { - LKL(_mutex); - if (!_workers) - { - LKU(_mutex); - break; - } + Evas_Preload_Pthread *work = data; - work = _workers; - _workers = EINA_INLIST_CONTAINER_GET(eina_inlist_remove(EINA_INLIST_GET(_workers), EINA_INLIST_GET(_workers)), Evas_Preload_Pthread_Worker); - LKU(_mutex); + if (work->func_cancel) work->func_cancel(work->data); - if (work->func_heavy) work->func_heavy(work->data); - evas_async_events_put(pth, 0, work, _evas_preload_thread_done); - } - - LKL(_mutex); - if (_workers) - { - LKU(_mutex); - goto on_error; - } - _threads_count--; - LKU(_mutex); + _evas_preload_thread_work_free(work); +} - // dummy worker to wake things up - work = malloc(sizeof(Evas_Preload_Pthread_Worker)); - if (!work) return NULL; +static void +_evas_preload_thread_worker(void *data, Ecore_Thread *thread) +{ + Evas_Preload_Pthread *work = data; - work->data = pth; - work->func_heavy = NULL; - work->func_end = (_evas_preload_pthread_func) _evas_preload_thread_end; - work->func_cancel = NULL; - work->cancel = EINA_FALSE; + work->thread = thread; - evas_async_events_put(pth, 0, work, _evas_preload_thread_done); - return pth; + work->func_heavy(work->data); } void _evas_preload_thread_init(void) { - _threads_max = eina_cpu_count(); - if (_threads_max < 1) _threads_max = 1; - - LKI(_mutex); + ecore_init(); } void _evas_preload_thread_shutdown(void) { - /* FIXME: If function are still running in the background, should we kill them ? */ - Evas_Preload_Pthread_Worker *work; + Evas_Preload_Pthread *work; + + EINA_INLIST_FOREACH(works, work) + ecore_thread_cancel(work->thread); - /* Force processing of async events. */ - evas_async_events_process(); - LKL(_mutex); - while (_workers) + while (works) { - work = _workers; - _workers = EINA_INLIST_CONTAINER_GET(eina_inlist_remove(EINA_INLIST_GET(_workers), EINA_INLIST_GET(_workers)), Evas_Preload_Pthread_Worker); - if (work->func_cancel) work->func_cancel(work->data); - free(work); + work = (Evas_Preload_Pthread*) works; + if (!ecore_thread_wait(work->thread, 1)) + { + ERR("Can not wait any longer on Evas thread to be done during shutdown. This might lead to a crash."); + works = eina_inlist_remove(works, works); + } } - LKU(_mutex); - - LKD(_mutex); + ecore_shutdown(); } Evas_Preload_Pthread * @@ -148,10 +100,9 @@ evas_preload_thread_run(void (*func_heavy) (void *data), void (*func_cancel) (void *data), const void *data) { - Evas_Preload_Pthread_Worker *work; - Evas_Preload_Pthread_Data *pth; + Evas_Preload_Pthread *work; - work = malloc(sizeof(Evas_Preload_Pthread_Worker)); + work = malloc(sizeof(Evas_Preload_Pthread)); if (!work) { func_cancel((void *)data); @@ -161,70 +112,22 @@ evas_preload_thread_run(void (*func_heavy) (void *data), work->func_heavy = func_heavy; work->func_end = func_end; work->func_cancel = func_cancel; - work->cancel = EINA_FALSE; work->data = (void *)data; - LKL(_mutex); - _workers = (Evas_Preload_Pthread_Worker *)eina_inlist_append(EINA_INLIST_GET(_workers), EINA_INLIST_GET(work)); - if (_threads_count == _threads_max) - { - LKU(_mutex); - return (Evas_Preload_Pthread *)work; - } - LKU(_mutex); - - /* One more thread could be created. */ - pth = malloc(sizeof(Evas_Preload_Pthread_Data)); - if (!pth) goto on_error; - - eina_threads_init(); - - if (eina_thread_create(&pth->thread, EINA_THREAD_BACKGROUND, -1, _evas_preload_thread_worker, pth)) - { - LKL(_mutex); - _threads_count++; - LKU(_mutex); - return (Evas_Preload_Pthread*)work; - } + work->thread = ecore_thread_run(_evas_preload_thread_worker, + _evas_preload_thread_success, + _evas_preload_thread_fail, + work); + if (!work->thread) + return NULL; - eina_threads_shutdown(); + works = eina_inlist_prepend(works, EINA_INLIST_GET(work)); -on_error: - LKL(_mutex); - if (_threads_count == 0) - { - _workers = EINA_INLIST_CONTAINER_GET(eina_inlist_remove(EINA_INLIST_GET(_workers), EINA_INLIST_GET(work)), Evas_Preload_Pthread_Worker); - LKU(_mutex); - if (work->func_cancel) work->func_cancel(work->data); - free(work); - return NULL; - } - LKU(_mutex); - return NULL; + return work; } Eina_Bool -evas_preload_thread_cancel(Evas_Preload_Pthread *thread) +evas_preload_thread_cancel(Evas_Preload_Pthread *work) { - Evas_Preload_Pthread_Worker *work; - - if (!thread) return EINA_TRUE; - LKL(_mutex); - EINA_INLIST_FOREACH(_workers, work) - { - if (work == (Evas_Preload_Pthread_Worker *)thread) - { - _workers = EINA_INLIST_CONTAINER_GET(eina_inlist_remove(EINA_INLIST_GET(_workers), EINA_INLIST_GET(work)), Evas_Preload_Pthread_Worker); - LKU(_mutex); - if (work->func_cancel) work->func_cancel(work->data); - free(work); - return EINA_TRUE; - } - } - LKU(_mutex); - - /* Delay the destruction */ - work = (Evas_Preload_Pthread_Worker *)thread; - work->cancel = EINA_TRUE; - return EINA_FALSE; + return ecore_thread_cancel(work->thread); } --