Prevents the incorrect signal on gcond of wl_egl_buffer. 74/270174/1
authorJoonbum Ko <joonbum.ko@samsung.com>
Thu, 20 Jan 2022 08:16:52 +0000 (17:16 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Wed, 26 Jan 2022 06:57:50 +0000 (15:57 +0900)
  As with g_cond_wait() it is possible that a spurious or stolen wakeup
 could occur. For that reason, waiting on a condition variable should
 always be in a loop, based on an explicitly-checked predicate.

Change-Id: I388e71a48dc91c1636490c856698c4a7f8d3fafd
Signed-off-by: Joonbum Ko <joonbum.ko@samsung.com>
src/tpl_wl_egl_thread.c

index 44d8f92..95b9af0 100755 (executable)
@@ -2449,24 +2449,28 @@ __tpl_wl_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns,
                        _get_wl_egl_buffer(wl_egl_surface->last_enq_buffer);
 
                if (enqueued_buffer) {
+                       tbm_surface_internal_ref(wl_egl_surface->last_enq_buffer);
+                       tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
                        tpl_gmutex_lock(&enqueued_buffer->mutex);
-                       if (enqueued_buffer->status >= ENQUEUED &&
-                               enqueued_buffer->status < COMMITTED) {
+                       while (enqueued_buffer->status >= ENQUEUED &&
+                                  enqueued_buffer->status < COMMITTED) {
                                tpl_result_t wait_result;
                                TPL_INFO("[DEQ_AFTER_RESET]",
                                                 "waiting for previous wl_egl_buffer(%p) commit",
                                                 enqueued_buffer);
-                               tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
+
                                wait_result = tpl_cond_timed_wait(&enqueued_buffer->cond,
                                                                                                  &enqueued_buffer->mutex,
                                                                                                  200); /* 200ms */
-                               tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
                                if (wait_result == TPL_ERROR_TIME_OUT) {
                                        TPL_WARN("timeout occured waiting signaled. wl_egl_buffer(%p)",
                                                         enqueued_buffer);
+                                       break;
                                }
                        }
                        tpl_gmutex_unlock(&enqueued_buffer->mutex);
+                       tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
+                       tbm_surface_internal_unref(wl_egl_surface->last_enq_buffer);
                }
 
                wl_egl_surface->last_enq_buffer = NULL;