From: Joonbum Ko Date: Fri, 11 Oct 2024 02:28:36 +0000 (+0900) Subject: utils_gthread: modify thread's mutex locking mechanism X-Git-Tag: accepted/tizen/unified/20241017.114708~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9da4d201c74a48dfda7c25b03b8ec8aa511cad42;p=platform%2Fcore%2Fuifw%2Flibtpl-egl.git utils_gthread: modify thread's mutex locking mechanism - Add init_done flag to struct tpl_gthread to check if the initialization in thread is completed. - Remove unncessary locking mutex thread->thread_mutex. This fix can be resolve deadlock problem below. wake up thread _thread_source_dispatch g_mutex_lock -> lock thread_mutex // this locking is not neccessary __gsource_remove_and_destroy g_source_unref __thread_func_surf_finalize tpl_gmutex_lock -> lock surf_mutex _thread_wl_egl_surface_fini _buffers_force_release tbm_surface_internal_unref __cb_wl_egl_buffer_free tpl_gsource_destroy -> lock thread_mutex // it will cause deadlock Change-Id: I8c755173efaff57da2384f9fb88c8cdd651b2217 Signed-off-by: Joonbum Ko --- diff --git a/src/tpl_utils_gthread.c b/src/tpl_utils_gthread.c index a0b1fb7..167e216 100644 --- a/src/tpl_utils_gthread.c +++ b/src/tpl_utils_gthread.c @@ -12,6 +12,7 @@ struct _tpl_gthread { GMutex pause_mutex; tpl_bool_t is_idle; tpl_bool_t paused; + tpl_bool_t init_done; tpl_gthread_func init_func; void *func_data; @@ -47,6 +48,7 @@ _tpl_gthread_init(gpointer data) if (thread->init_func) thread->init_func(thread->func_data); + thread->init_done = TPL_TRUE; g_cond_signal(&thread->thread_cond); g_mutex_unlock(&thread->thread_mutex); @@ -98,6 +100,7 @@ tpl_gthread_create(const char *thread_name, new_thread->is_idle = TPL_FALSE; new_thread->paused = TPL_FALSE; + new_thread->init_done = TPL_FALSE; g_mutex_lock(&new_thread->thread_mutex); @@ -106,8 +109,11 @@ tpl_gthread_create(const char *thread_name, new_thread->func_data = func_data; new_thread->thread = g_thread_new(thread_name, _tpl_gthread_init, new_thread); - g_cond_wait(&new_thread->thread_cond, - &new_thread->thread_mutex); + + while (!new_thread->init_done) { + g_cond_wait(&new_thread->thread_cond, + &new_thread->thread_mutex); + } g_mutex_unlock(&new_thread->thread_mutex); @@ -187,6 +193,7 @@ _thread_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) ssize_t s; uint64_t message = 0; + g_mutex_lock(&thread->thread_mutex); if (gsource->fd_type == FD_TYPE_EVENT) { s = read(gsource->fd, &message, sizeof(uint64_t)); if (s != sizeof(uint64_t)) { @@ -194,6 +201,7 @@ _thread_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) gsource->fd); } } + g_mutex_unlock(&thread->thread_mutex); if (gsource->gsource_funcs && gsource->gsource_funcs->dispatch) ret = gsource->gsource_funcs->dispatch(gsource, message); @@ -202,14 +210,8 @@ _thread_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) gsource->intended_destroy == TPL_TRUE) { tpl_gsource *del_source = (tpl_gsource *)gsource->data; if (!g_source_is_destroyed(&del_source->gsource)) { - g_mutex_lock(&thread->thread_mutex); - __gsource_remove_and_destroy(del_source); __gsource_remove_and_destroy(gsource); - - g_cond_signal(&thread->thread_cond); - g_mutex_unlock(&thread->thread_mutex); - return G_SOURCE_REMOVE; } } @@ -228,10 +230,7 @@ _thread_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) } if (gsource->type == SOURCE_TYPE_DISPOSABLE) { - g_mutex_lock(&thread->thread_mutex); __gsource_remove_and_destroy(gsource); - ret = G_SOURCE_REMOVE; - g_mutex_unlock(&thread->thread_mutex); } return ret; @@ -340,14 +339,15 @@ tpl_gsource_destroy(tpl_gsource *source, tpl_bool_t destroy_in_thread) return; } - g_mutex_lock(&thread->thread_mutex); if (source->type == SOURCE_TYPE_NORMAL && source->finalizer) { tpl_gsource *finalizer = source->finalizer; if (destroy_in_thread) { finalizer->intended_destroy = TPL_TRUE; + g_mutex_lock(&thread->thread_mutex); tpl_gsource_send_message(finalizer, 1); + g_mutex_unlock(&thread->thread_mutex); } else { __gsource_remove_and_destroy(finalizer); source->finalizer = NULL; @@ -368,8 +368,6 @@ tpl_gsource_destroy(tpl_gsource *source, tpl_bool_t destroy_in_thread) else __gsource_remove_and_destroy(source); } - - g_mutex_unlock(&thread->thread_mutex); } void @@ -631,9 +629,7 @@ tpl_gthread_add_idle(tpl_gthread *gthread, tpl_gsource_func idle_cb, void *data) idle_cb, (gpointer)data, NULL); - g_mutex_lock(>hread->thread_mutex); id = g_source_attach(idle_source, g_main_loop_get_context(gthread->loop)); - g_mutex_unlock(>hread->thread_mutex); g_source_unref(idle_source); return id;