modify the locking buffer->mutex to include surface_commit 97/304497/1
authorjinbong, Lee <jinbong.lee@samsung.com>
Tue, 19 Sep 2023 04:50:56 +0000 (13:50 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Fri, 12 Jan 2024 12:06:09 +0000 (21:06 +0900)
 - In the case when _thread_wl_surface_commit() is called after
  the mutex of wl_egl_buffer has been unlocked in the thread,
  the wl_egl_buffer may be freed in the parent thread.
 - In that case, a problem occurs during commit operation.
  Therefore, the buffer must be maintained until the commit is completed.

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

index 5621065..a3abe39 100755 (executable)
@@ -112,7 +112,6 @@ struct _tpl_wl_egl_surface {
        tpl_surface_vblank_t         *vblank;
 
        /* surface information */
-       int                           render_done_cnt;
        unsigned int                  serial;
 
        int                           width;
@@ -1772,7 +1771,6 @@ __tpl_wl_egl_surface_init(tpl_surface_t *surface)
        wl_egl_surface->frontbuffer_activated  = TPL_FALSE;
 
        wl_egl_surface->latest_transform       = -1;
-       wl_egl_surface->render_done_cnt        = 0;
        wl_egl_surface->serial                 = 0;
 
        wl_egl_surface->vblank                 = NULL;
@@ -2878,15 +2876,15 @@ __thread_func_waiting_source_dispatch(tpl_gsource *gsource, uint64_t message)
        TPL_CHECK_ON_NULL_RETURN_VAL(tbm_surface, TPL_FALSE);
        TPL_CHECK_ON_FALSE_RETURN_VAL(tbm_surface_internal_is_valid(tbm_surface), TPL_FALSE);
 
-       wl_egl_surface->render_done_cnt++;
-
        TRACE_ASYNC_END(wl_egl_buffer->acquire_fence_fd, "FENCE WAIT fd(%d)",
                                        wl_egl_buffer->acquire_fence_fd);
 
        TPL_LOG_D("[RENDER DONE]", "wl_egl_surface(%p) wl_egl_buffer(%p) tbm_surface(%p)",
                          wl_egl_surface, wl_egl_buffer, tbm_surface);
 
+       tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
        tpl_gmutex_lock(&wl_egl_buffer->mutex);
+
        wl_egl_buffer->status = WAITING_VBLANK;
 
        TPL_LOG_D("[FINALIZE]", "wl_egl_surface(%p) wl_egl_buffer(%p) wait_source(%p) fence_fd(%d)",
@@ -2896,19 +2894,17 @@ __thread_func_waiting_source_dispatch(tpl_gsource *gsource, uint64_t message)
        wl_egl_buffer->acquire_fence_fd = -1;
        wl_egl_buffer->waiting_source = NULL;
 
-       tpl_gmutex_unlock(&wl_egl_buffer->mutex);
-
-       tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
-
-       if (!wl_egl_surface->vblank_enable || wl_egl_surface->vblank_done)
+       if (!wl_egl_surface->vblank_enable || wl_egl_surface->vblank_done) {
                _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer);
-       else {
+               tpl_gcond_signal(&wl_egl_buffer->cond);
+       } else {
                tpl_gmutex_lock(&wl_egl_surface->vblank->mutex);
                __tpl_list_push_back(wl_egl_surface->vblank->waiting_buffers,
                                                         wl_egl_buffer);
                tpl_gmutex_unlock(&wl_egl_surface->vblank->mutex);
        }
 
+       tpl_gmutex_unlock(&wl_egl_buffer->mutex);
        tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
 
        return TPL_FALSE;
@@ -2999,10 +2995,12 @@ _thread_surface_queue_acquire(tpl_wl_egl_surface_t *wl_egl_surface)
                        }
                }
 
-               tpl_gmutex_unlock(&wl_egl_buffer->mutex);
-
-               if (ready_to_commit)
+               if (ready_to_commit) {
                        _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer);
+                       tpl_gcond_signal(&wl_egl_buffer->cond);
+               }
+
+               tpl_gmutex_unlock(&wl_egl_buffer->mutex);
        }
 
        return TPL_ERROR_NONE;
@@ -3037,7 +3035,10 @@ __cb_tdm_client_vblank(tdm_client_vblank *vblank, tdm_error error,
 
                        if (!wl_egl_buffer) break;
 
+                       tpl_gmutex_lock(&wl_egl_buffer->mutex);
                        _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer);
+                       tpl_gcond_signal(&wl_egl_buffer->cond);
+                       tpl_gmutex_unlock(&wl_egl_buffer->mutex);
 
                        /* If tdm error such as TIMEOUT occured,
                         * flush all vblank waiting buffers of its wl_egl_surface.
@@ -3502,17 +3503,11 @@ _thread_wl_surface_commit(tpl_wl_egl_surface_t *wl_egl_surface,
        TRACE_ASYNC_BEGIN((intptr_t)wl_egl_buffer->tbm_surface, "[COMMIT ~ RELEASE] BO(%d)",
                                          wl_egl_buffer->bo_name);
 
-       tpl_gmutex_lock(&wl_egl_buffer->mutex);
-
        wl_egl_buffer->need_to_commit   = TPL_FALSE;
        wl_egl_buffer->status           = COMMITTED;
        if (wl_egl_surface->last_enq_buffer == wl_egl_buffer->tbm_surface)
                wl_egl_surface->last_enq_buffer = NULL;
 
-       tpl_gcond_signal(&wl_egl_buffer->cond);
-
-       tpl_gmutex_unlock(&wl_egl_buffer->mutex);
-
        TPL_LOG_T("WL_EGL",
                          "[COMMIT] wl_egl_buffer(%p) wl_buffer(%p) tbm_surface(%p) bo(%d)",
                          wl_egl_buffer, wl_egl_buffer->wl_buffer, wl_egl_buffer->tbm_surface,
@@ -3615,8 +3610,10 @@ __cb_wl_egl_buffer_free(tpl_wl_egl_buffer_t *wl_egl_buffer)
        tpl_wl_egl_surface_t *wl_egl_surface = wl_egl_buffer->wl_egl_surface;
        tpl_wl_egl_display_t *wl_egl_display = wl_egl_surface->wl_egl_display;
 
-       TPL_INFO("[BUFFER_FREE]", "wl_egl_surface(%p) wl_egl_buffer(%p) tbm_surface(%p) bo(%d)",
-                        wl_egl_surface, wl_egl_buffer, wl_egl_buffer->tbm_surface, wl_egl_buffer->bo_name);
+       TPL_INFO("[BUFFER_FREE]", "wl_egl_surface(%p) wl_egl_buffer(%p)",
+                        wl_egl_surface, wl_egl_buffer);
+       TPL_INFO("[BUFFER_FREE]", "tbm_surface(%p) bo(%d)",
+                        wl_egl_buffer->tbm_surface, wl_egl_buffer->bo_name);
 
        tpl_gmutex_lock(&wl_egl_surface->buffers_mutex);
        if (wl_egl_surface->buffers) {