From: Joonbum Ko Date: Mon, 28 Dec 2020 12:10:00 +0000 (+0900) Subject: Add finalizer source to tpl_gsource X-Git-Tag: submit/tizen/20210316.021228~36 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d8f9743174f8059825bc6904bc7f47d1a8ed5640;p=platform%2Fcore%2Fuifw%2Flibtpl-egl.git Add finalizer source to tpl_gsource - The finalizer source can only be had when the type of tpl_gsource is SOURCE_TYPE_NORMAL. - The finalizer allows a source of NORMAL type to be safely finalized inside a thread. Change-Id: I143b9fe52bc38b65f7649115b3a757b572ce1cd0 Signed-off-by: Joonbum Ko --- diff --git a/src/tpl_utils_gthread.c b/src/tpl_utils_gthread.c index 6d84137..5678755 100644 --- a/src/tpl_utils_gthread.c +++ b/src/tpl_utils_gthread.c @@ -25,6 +25,7 @@ struct _tpl_gsource { tpl_gsource_functions *gsource_funcs; tpl_gsource_type_t type; + tpl_gsource *finalizer; void *data; }; @@ -139,6 +140,7 @@ tpl_gthread_destroy(tpl_gthread *thread, tpl_gthread_func deinit_func) thread->func = NULL; free(thread); + thread = NULL; } static gboolean @@ -147,7 +149,10 @@ _thread_source_prepare(GSource *source, gint *time) tpl_gsource *gsource = (tpl_gsource *)source; tpl_bool_t ret = TPL_FALSE; - if (gsource->gsource_funcs->prepare) + if (gsource->type != SOURCE_TYPE_NORMAL) + return ret; + + if (gsource->gsource_funcs && gsource->gsource_funcs->prepare) ret = gsource->gsource_funcs->prepare(gsource); *time = -1; @@ -161,7 +166,10 @@ _thread_source_check(GSource *source) tpl_gsource *gsource = (tpl_gsource *)source; tpl_bool_t ret = TPL_FALSE; - if (gsource->gsource_funcs->check) + if (gsource->type != SOURCE_TYPE_NORMAL) + return ret; + + if (gsource->gsource_funcs && gsource->gsource_funcs->check) ret = gsource->gsource_funcs->check(gsource); return ret; @@ -175,11 +183,24 @@ _thread_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) GIOCondition cond = g_source_query_unix_fd(source, gsource->tag); TPL_IGNORE(cb); - TPL_IGNORE(data); if (cond & G_IO_IN) { - if (gsource->gsource_funcs->dispatch) + if (gsource->gsource_funcs && gsource->gsource_funcs->dispatch) ret = gsource->gsource_funcs->dispatch(gsource); + + if (gsource->type == SOURCE_TYPE_FINALIZER) { + tpl_gsource *del_source = (tpl_gsource *)data; + if (!g_source_is_destroyed(&del_source->gsource)) { + g_mutex_lock(&del_source->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); + + g_cond_signal(&del_source->thread->thread_cond); + g_mutex_unlock(&del_source->thread_mutex); + } + } } else { /* When some io errors occur, it is not considered as a critical error. * There may be problems with the screen, but it does not affect the operation. */ @@ -187,8 +208,13 @@ _thread_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) gsource, gsource->fd, cond); } - if (gsource->type == SOURCE_TYPE_DISPOSABLE) + 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); ret = TPL_GSOURCE_REMOVE; + } return ret; } @@ -198,7 +224,7 @@ _thread_source_finalize(GSource *source) { tpl_gsource *gsource = (tpl_gsource *)source; - if (gsource->gsource_funcs->finalize) + if (gsource->gsource_funcs && gsource->gsource_funcs->finalize) gsource->gsource_funcs->finalize(gsource); if (gsource->is_eventfd) @@ -208,6 +234,7 @@ _thread_source_finalize(GSource *source) gsource->thread = NULL; gsource->gsource_funcs = NULL; gsource->data = NULL; + gsource->finalizer = NULL; } static GSourceFuncs _thread_source_funcs = { @@ -249,6 +276,13 @@ tpl_gsource_create(tpl_gthread *thread, void *data, int fd, new_gsource->data = data; new_gsource->type = type; + if (new_gsource->type == SOURCE_TYPE_NORMAL) { + tpl_gsource *finalizer = tpl_gsource_create(thread, new_gsource, -1, + NULL, SOURCE_TYPE_FINALIZER); + new_gsource->finalizer = finalizer; + } else + new_gsource->finalizer = NULL; + new_gsource->tag = g_source_add_unix_fd(&new_gsource->gsource, new_gsource->fd, G_IO_IN | G_IO_ERR); @@ -261,9 +295,30 @@ tpl_gsource_create(tpl_gthread *thread, void *data, int fd, void tpl_gsource_destroy(tpl_gsource *source) { - g_source_remove_unix_fd(&source->gsource, source->tag); - g_source_destroy(&source->gsource); - g_source_unref(&source->gsource); + if (g_source_is_destroyed(&source->gsource)) { + TPL_WARN("gsource(%p) already has been destroyed.", + source); + return; + } + + if (source->type == SOURCE_TYPE_NORMAL && + source->finalizer != NULL) { + 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); + } + + + 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); + } } void @@ -272,7 +327,7 @@ tpl_gsource_send_event(tpl_gsource *source, uint64_t message) uint64_t value = message; int ret; - ret = write(del_source->event_fd, &value, sizeof(uint64_t)); + ret = write(source->event_fd, &value, sizeof(uint64_t)); if (ret == -1) { TPL_ERR("failed to send devent. tpl_gsource(%p)", source);