[UI Thread] Fix undefnied behavior of g_rec_mutex_clear() 38/273938/2
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 18 Apr 2022 10:20:39 +0000 (19:20 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 18 Apr 2022 10:30:47 +0000 (19:30 +0900)
If an application uses UI thread feature, the aul_launch_fini() function
can be invoked each threads. In that time, the race condition about
g_rec_mutex_clear() can be occurred. This patch initializes the
recursive mutex in the constructor to prevent the issue.

Change-Id: Ie01ec307ddd8fe3b9cbdb9925b2f6c37f93775e5
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/aul_launch.c

index 7c2c054..7a660fc 100644 (file)
@@ -43,6 +43,9 @@
 
 #define K_SERVICE_THREAD "__K_SERVICE_THREAD"
 
+#define AUL_CTOR __attribute__ ((constructor))
+#define AUL_DTOR __attribute__ ((destructor))
+
 typedef struct client_channel_s {
        int fd;
        pid_t pid;
@@ -89,6 +92,19 @@ typedef struct launch_context_s {
 
 static launch_context __context;
 
+AUL_CTOR static void __aul_constructor(void)
+{
+       g_rec_mutex_init(&__context.mutex);
+}
+
+AUL_DTOR static void __aul_destructor(void)
+{
+       if (g_rec_mutex_trylock(&__context.mutex))
+               g_rec_mutex_unlock(&__context.mutex);
+
+       g_rec_mutex_clear(&__context.mutex);
+}
+
 static void __destroy_client_channel(gpointer data)
 {
        client_channel_t *channel = data;
@@ -614,8 +630,11 @@ static bool __connected_event_cb(int fd, int condition, void *user_data)
 
 static void __finalize_context(void)
 {
-       if (!__context.initialized)
+       g_rec_mutex_lock(&__context.mutex);
+       if (!__context.initialized) {
+               g_rec_mutex_unlock(&__context.mutex);
                return;
+       }
 
        __context.touch_argv_handler = false;
 
@@ -629,16 +648,13 @@ static void __finalize_context(void)
                __context.tizen_context = NULL;
        }
 
-       g_rec_mutex_lock(&__context.mutex);
        if (__context.clients) {
                g_list_free_full(__context.clients, __destroy_client_channel);
                __context.clients = NULL;
        }
 
-       g_rec_mutex_unlock(&__context.mutex);
-       g_rec_mutex_clear(&__context.mutex);
-
        __context.initialized = false;
+       g_rec_mutex_unlock(&__context.mutex);
 }
 
 static GMainContext *__get_tizen_glib_context(void)
@@ -676,8 +692,6 @@ static int __initialize_context(void)
                return fd;
        }
 
-       g_rec_mutex_init(&__context.mutex);
-
        context = __get_tizen_glib_context();
        if (context)
                __context.tizen_context = g_main_context_ref(context);
@@ -704,12 +718,18 @@ static int __initialize_context(void)
 
 API int aul_launch_init(aul_handler_fn callback, void *user_data)
 {
+       int ret;
+
+       g_rec_mutex_lock(&__context.mutex);
        if (callback) {
                __context.aul.callback = callback;
                __context.aul.user_data = user_data;
        }
 
-       return __initialize_context();
+       ret = __initialize_context();
+       g_rec_mutex_unlock(&__context.mutex);
+
+       return ret;
 }
 
 API int aul_launch_fini(void)