From: Joonbum Ko Date: Wed, 24 Mar 2021 10:48:31 +0000 (+0900) Subject: Add intended_destroy flag to destroy only when intended. X-Git-Tag: submit/tizen/20210325.043850~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=98e734005b6b0548fc00773f89237d9a27dd4e92;p=platform%2Fcore%2Fuifw%2Flibtpl-egl.git Add intended_destroy flag to destroy only when intended. - G_IO_IN may occur in eventfd of finalizer source due to some unexpected errors. In this case, if gsource destroyed in unintended, a fatal problem may occur in thread. - The intended_destroy flag of the newly added to tpl_gsource will help the finalizer source to operate normally only if it is intended G_IO_IN. Change-Id: I6dd6a2de7e3c4ff667f8d639e30783584e6e8cec Signed-off-by: Joonbum Ko --- diff --git a/src/tpl_utils_gthread.c b/src/tpl_utils_gthread.c index b024088..47a7041 100644 --- a/src/tpl_utils_gthread.c +++ b/src/tpl_utils_gthread.c @@ -23,10 +23,13 @@ struct _tpl_gsource { tpl_gsource_type_t type; tpl_gsource *finalizer; + tpl_bool_t intended_destroy; void *data; }; +static void +__gsource_remove_and_destroy(tpl_gsource *source); static gpointer _tpl_gthread_init(gpointer data) @@ -175,15 +178,14 @@ _thread_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) if (gsource->gsource_funcs && gsource->gsource_funcs->dispatch) ret = gsource->gsource_funcs->dispatch(gsource, message); - if (gsource->type == SOURCE_TYPE_FINALIZER) { + if (gsource->type == SOURCE_TYPE_FINALIZER && + gsource->intended_destroy == TPL_TRUE) { tpl_gsource *del_source = (tpl_gsource *)gsource->data; if (!g_source_is_destroyed(&del_source->gsource)) { tpl_gthread *thread = del_source->thread; g_mutex_lock(&thread->thread_mutex); - g_source_remove_unix_fd(&del_source->gsource, del_source->tag); - g_source_destroy(&del_source->gsource); - g_source_unref(&del_source->gsource); + __gsource_remove_and_destroy(del_source); g_cond_signal(&thread->thread_cond); g_mutex_unlock(&thread->thread_mutex); @@ -200,9 +202,7 @@ _thread_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) if (gsource->type == SOURCE_TYPE_DISPOSABLE || gsource->type == SOURCE_TYPE_FINALIZER) { - g_source_remove_unix_fd(&gsource->gsource, gsource->tag); - g_source_destroy(&gsource->gsource); - g_source_unref(&gsource->gsource); + __gsource_remove_and_destroy(gsource); ret = G_SOURCE_REMOVE; } @@ -265,6 +265,7 @@ tpl_gsource_create(tpl_gthread *thread, void *data, int fd, new_gsource->gsource_funcs = funcs; new_gsource->data = data; new_gsource->type = type; + new_gsource->intended_destroy = TPL_FALSE; if (new_gsource->type == SOURCE_TYPE_NORMAL) { tpl_gsource *finalizer = tpl_gsource_create(thread, new_gsource, -1, @@ -285,6 +286,17 @@ tpl_gsource_create(tpl_gthread *thread, void *data, int fd, return new_gsource; } +static void +__gsource_remove_and_destroy(tpl_gsource *source) +{ + TPL_DEBUG("[GSOURCE_DESTROY] tpl_gsource(%p) type(%d)", + source, source->type); + + g_source_remove_unix_fd(&source->gsource, source->tag); + g_source_destroy(&source->gsource); + g_source_unref(&source->gsource); +} + void tpl_gsource_destroy(tpl_gsource *source, tpl_bool_t destroy_in_thread) { @@ -294,32 +306,27 @@ tpl_gsource_destroy(tpl_gsource *source, tpl_bool_t destroy_in_thread) return; } - TPL_DEBUG("[GSOURCE_DESTROY] tpl_gsource(%p) type(%d)", - source, source->type); + if (source->type == SOURCE_TYPE_NORMAL && + source->finalizer) { + tpl_gsource *finalizer = source->finalizer; - if (destroy_in_thread) { - tpl_gthread *thread = source->thread; - if (source->type == SOURCE_TYPE_NORMAL) { + if (destroy_in_thread) { + tpl_gthread *thread = source->thread; g_mutex_lock(&thread->thread_mutex); - tpl_gsource_send_message(source->finalizer, 1); + finalizer->intended_destroy = TPL_TRUE; + tpl_gsource_send_message(finalizer, 1); g_cond_wait(&thread->thread_cond, &thread->thread_mutex); g_mutex_unlock(&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); + } else { + __gsource_remove_and_destroy(finalizer); source->finalizer = NULL; } + } - g_source_remove_unix_fd(&source->gsource, source->tag); - g_source_destroy(&source->gsource); - g_source_unref(&source->gsource); + if (!destroy_in_thread) { + __gsource_remove_and_destroy(source); } }