cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=e6ff0a53ae7b1fc526ac88067b71337d6e271f0c
commit e6ff0a53ae7b1fc526ac88067b71337d6e271f0c Author: Cedric BAIL <[email protected]> Date: Wed Jan 7 16:43:47 2015 +0100 eio: forcefully wait on shutdown for all thread to stop. This should avoid potential crash during shutdown while some Eio thread were still running. We are still not blocking for more than 30s, so if an IO is blocked on a dead device, you should be fine. --- src/lib/eio/eio_main.c | 31 +++++++++++++++++++++++++++++-- src/lib/eio/eio_private.h | 3 +++ src/lib/eio/eio_single.c | 13 +++++++++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/lib/eio/eio_main.c b/src/lib/eio/eio_main.c index 812437d..f084cb7 100644 --- a/src/lib/eio/eio_main.c +++ b/src/lib/eio/eio_main.c @@ -233,6 +233,22 @@ eio_pack_send(Ecore_Thread *thread, Eina_List *pack, double *start) return pack; } +// For now use a list for simplicity and we should not have that many +// pending request +static Eina_List *tracked_thread = NULL; + +void +eio_file_register(Eio_File *common) +{ + tracked_thread = eina_list_append(tracked_thread, common); +} + +void +eio_file_unregister(Eio_File *common) +{ + tracked_thread = eina_list_remove(tracked_thread, common); +} + /** * @endcond */ @@ -308,6 +324,8 @@ eio_shutdown(void) Eio_File_Char *cin; Eio_Progress *pg; Eio_File_Associate *asso; + Eio_File *f; + Eina_List *l; if (_eio_init_count <= 0) { @@ -318,8 +336,17 @@ eio_shutdown(void) return _eio_init_count; eina_log_timing(_eio_log_dom_global, - EINA_LOG_STATE_START, - EINA_LOG_STATE_SHUTDOWN); + EINA_LOG_STATE_START, + EINA_LOG_STATE_SHUTDOWN); + + EINA_LIST_FOREACH(tracked_thread, l, f) + ecore_thread_cancel(f->thread); + + EINA_LIST_FREE(tracked_thread, f) + { + if (!ecore_thread_wait(f->thread, 0.5)) + CRI("We couldn't terminate in less than 30s some pending IO. This can led to some crash."); + } eio_monitor_shutdown(); diff --git a/src/lib/eio/eio_private.h b/src/lib/eio/eio_private.h index 8502713..b36360d 100644 --- a/src/lib/eio/eio_private.h +++ b/src/lib/eio/eio_private.h @@ -498,4 +498,7 @@ void eio_async_error(void *data, Ecore_Thread *thread); Eina_List *eio_pack_send(Ecore_Thread *thread, Eina_List *pack, double *start); +void eio_file_register(Eio_File *common); +void eio_file_unregister(Eio_File *common); + #endif diff --git a/src/lib/eio/eio_single.c b/src/lib/eio/eio_single.c index 1694bd6..1607cf3 100644 --- a/src/lib/eio/eio_single.c +++ b/src/lib/eio/eio_single.c @@ -326,6 +326,7 @@ eio_file_free(Eio_File *common) eina_hash_free(common->worker.associated); if (common->main.associated) eina_hash_free(common->main.associated); + eio_file_unregister(common); free(common); } @@ -359,7 +360,11 @@ eio_long_file_set(Eio_File *common, cancel_cb, common, EINA_FALSE); - if (thread) common->thread = thread; + if (thread) + { + common->thread = thread; + eio_file_register(common); + } return !!thread; } @@ -388,7 +393,11 @@ eio_file_set(Eio_File *common, */ thread = ecore_thread_run(job_cb, end_cb, cancel_cb, common); - if (thread) common->thread = thread; + if (thread) + { + common->thread = thread; + eio_file_register(common); + } return !!thread; } --
