utils_gthread: Prevent deadlock caused by wait_idle
[platform/core/uifw/libtpl-egl.git] / src / tpl_utils_gthread.c
index 208d881..bdc1109 100644 (file)
@@ -475,7 +475,7 @@ _thread_idle_cb(gpointer data)
 
        g_mutex_lock(&gthread->idle_mutex);
        gthread->is_idle = TPL_TRUE;
-       g_cond_signal(&gthread->idle_cond);
+       g_cond_broadcast(&gthread->idle_cond);
        g_mutex_unlock(&gthread->idle_mutex);
 
        /* If the caller thread of tpl_gthread_wait_idle locked the pause_mutex,
@@ -498,7 +498,10 @@ tpl_gthread_wait_idle(tpl_gthread *gthread)
        TPL_DEBUG("[WAIT IDLE] BEGIN");
 
        g_mutex_lock(&gthread->idle_mutex);
-       gthread->is_idle = TPL_FALSE;
+       if (gthread->is_idle) {
+               g_mutex_unlock(&gthread->idle_mutex);
+               return;
+       }
 
        idle_source = g_idle_source_new();
        if (idle_source == NULL) {
@@ -517,8 +520,7 @@ tpl_gthread_wait_idle(tpl_gthread *gthread)
        /* 200ms timeout */
        end_time = g_get_monotonic_time() +
                                (200 * G_TIME_SPAN_MILLISECOND);
-
-       while (!gthread->is_idle) {
+       do {
                ret = g_cond_wait_until(&gthread->idle_cond,
                                                                &gthread->idle_mutex,
                                                                end_time);
@@ -526,7 +528,10 @@ tpl_gthread_wait_idle(tpl_gthread *gthread)
                        TPL_ERR("wait_idle timeout!");
                        break;
                }
-       }
+       } while (!gthread->is_idle);
+
+       gthread->is_idle = TPL_FALSE;
+
        g_mutex_unlock(&gthread->idle_mutex);
 
        TPL_DEBUG("[WAIT IDLE] END");