From: Joonbum Ko Date: Tue, 5 Jan 2021 04:04:29 +0000 (+0900) Subject: Added argument to function tpl_gsource_destroy X-Git-Tag: submit/tizen/20210316.021228~34 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1c98c9ca0d023e6c5d0172b5dcf5750e466ffb8f;p=platform%2Fcore%2Fuifw%2Flibtpl-egl.git Added argument to function tpl_gsource_destroy - In an exceptional situation, there are cases where tpl_gsource_destroy should be called inside gthread. - In this case, if a source whose type is SOURCE_TYPE_NORMAL tries to destroy through finalizer, deadlock may occur. Therefore, when destroying in the same thread, destroy_in_thread must be set to FALSE. Change-Id: I53a7b376f6cc12fbab12ec6d7bf6cc8e812eaa87 Signed-off-by: Joonbum Ko --- diff --git a/src/tpl_utils_gthread.c b/src/tpl_utils_gthread.c index 5678755..f178def 100644 --- a/src/tpl_utils_gthread.c +++ b/src/tpl_utils_gthread.c @@ -293,7 +293,7 @@ tpl_gsource_create(tpl_gthread *thread, void *data, int fd, } void -tpl_gsource_destroy(tpl_gsource *source) +tpl_gsource_destroy(tpl_gsource *source, tpl_bool_t destroy_in_thread) { if (g_source_is_destroyed(&source->gsource)) { TPL_WARN("gsource(%p) already has been destroyed.", @@ -301,20 +301,25 @@ tpl_gsource_destroy(tpl_gsource *source) return; } - if (source->type == SOURCE_TYPE_NORMAL && - source->finalizer != NULL) { - g_mutex_lock(&source->thread->thread_mutex); + if (destroy_in_thread) { + if (source->type == SOURCE_TYPE_NORMAL) { + g_mutex_lock(&source->thread->thread_mutex); - tpl_gsource_send_event(source->finalizer, 1); - - g_cond_wait(&source->thread->thread_cond, &source->thread->thread_mutex); - g_mutex_unlock(&source->thread->thread_mutex); - } + tpl_gsource_send_event(source->finalizer, 1); + g_cond_wait(&source->thread->thread_cond, &source->thread->thread_mutex); + g_mutex_unlock(&source->thread->thread_mutex); + } + } else { + if (source->type == SOURCE_TYPE_NORMAL && + source->finalizer) { + tpl_gsource *finalize = source->finalizer; + g_source_remove_unix_fd(&finalize->gsource, finalize->tag); + g_source_destroy(&finalize->gsource); + g_source_unref(&finalize->gsource); + source->finalizer = NULL; + } - if (!g_source_is_destroyed(&source->gsource) && - !(source->type == SOURCE_TYPE_DISPOSABLE || - source->type == SOURCE_TYPE_FINALIZER)) { g_source_remove_unix_fd(&source->gsource, source->tag); g_source_destroy(&source->gsource); g_source_unref(&source->gsource); diff --git a/src/tpl_utils_gthread.h b/src/tpl_utils_gthread.h index 4da3828..06d32e6 100644 --- a/src/tpl_utils_gthread.h +++ b/src/tpl_utils_gthread.h @@ -89,9 +89,12 @@ tpl_gsource_create(tpl_gthread *thread, void *data, int fd, * Detach the passed tpl_gsource from thread and destroy it. * * @param source Pointer to tpl_gsource to destroy. + * @param destroy_in_thread TRUE if destroy in thread through eventfd, FALSE otherwise. + * It is valid only when SOURCE_TYPE is NORMAL. + * @see tpl_gsource_type_t tpl_gsource_create */ void -tpl_gsource_destroy(tpl_gsource *source); +tpl_gsource_destroy(tpl_gsource *source, tpl_bool_t destroy_in_thread); /** * Send an event to dispatch the gsource attached to the thread. diff --git a/src/tpl_wl_egl.c b/src/tpl_wl_egl.c index 76947c6..c0e1416 100644 --- a/src/tpl_wl_egl.c +++ b/src/tpl_wl_egl.c @@ -227,7 +227,7 @@ __thread_func_tdm_dispatch(tpl_gsource *gsource) tdm_err); TPL_WARN("tdm_source(%p) will be removed from thread.", gsource); - tpl_gsource_destroy(gsource); + tpl_gsource_destroy(gsource, TPL_FALSE); wl_egl_display->tdm_source = NULL; @@ -521,7 +521,7 @@ _thread_fini(void *data) tpl_wl_egl_display_t *wl_egl_display = (tpl_wl_egl_display_t *)data; if (wl_egl_display->tdm_initialized) - tpl_gsource_destroy(wl_egl_display->tdm_source); + tpl_gsource_destroy(wl_egl_display->tdm_source, TPL_FALSE); if (wl_egl_display->wl_initialized) _thread_wl_display_fini(wl_egl_display); } @@ -617,7 +617,7 @@ __tpl_wl_egl_display_init(tpl_display_t *display) free_display: if (wl_egl_display->thread) { - tpl_gsource_destroy(wl_egl_display->tdm_source); + tpl_gsource_destroy(wl_egl_display->tdm_source, TPL_TRUE); tpl_gthread_destroy(wl_egl_display->thread, _thread_fini); } @@ -644,12 +644,12 @@ __tpl_wl_egl_display_fini(tpl_display_t *display) wl_egl_display->wl_display); if (wl_egl_display->gsource) { - tpl_gsource_destroy(wl_egl_display->gsource); + tpl_gsource_destroy(wl_egl_display->gsource, TPL_TRUE); wl_egl_display->gsource = NULL; } if (wl_egl_display->tdm_source && wl_egl_display->tdm_initialized) { - tpl_gsource_destroy(wl_egl_display->tdm_source); + tpl_gsource_destroy(wl_egl_display->tdm_source, TPL_TRUE); wl_egl_display->tdm_source = NULL; }