wl_egl: close fence_fd when gsource finalized 94/295594/1
authorJoonbum Ko <joonbum.ko@samsung.com>
Tue, 11 Jul 2023 06:33:48 +0000 (15:33 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Tue, 11 Jul 2023 09:35:16 +0000 (18:35 +0900)
 - Even though when main thread have called tpl_gsource_destroy for
  fence_waiting_source, which has not yet signaled, gsource may not be
  completely destroyed because it might be in dispatch queue in g_main_context.

 - In this case, if the fence_waiting_source is dispatched, it can try
  to commit with the invalid wl_egl_buffer that has already been freed.

 - This commit makes to prevent operating with an invalid wl_egl_buffer
  and to close fence_fd properly.

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

index 8406753..6020a67 100644 (file)
@@ -245,7 +245,8 @@ _thread_source_finalize(GSource *source)
        if (gsource->gsource_funcs && gsource->gsource_funcs->finalize)
                gsource->gsource_funcs->finalize(gsource);
 
-       if (gsource->fd_type == FD_TYPE_EVENT)
+       if (gsource->fd_type == FD_TYPE_EVENT ||
+               gsource->fd_type == FD_TYPE_FENCE)
                close(gsource->fd);
 
        gsource->fd = -1;
@@ -326,6 +327,8 @@ __gsource_remove_and_destroy(tpl_gsource *source)
        g_source_remove_unix_fd(&source->gsource, source->tag);
        g_source_destroy(&source->gsource);
        g_source_unref(&source->gsource);
+
+       source->data = NULL;
 }
 
 void
@@ -336,6 +339,7 @@ tpl_gsource_destroy(tpl_gsource *source, tpl_bool_t destroy_in_thread)
        if (g_source_is_destroyed(&source->gsource)) {
                TPL_WARN("gsource(%p) already has been destroyed.",
                                 source);
+               source->data = NULL;
                return;
        }
 
@@ -356,6 +360,7 @@ tpl_gsource_destroy(tpl_gsource *source, tpl_bool_t destroy_in_thread)
        if (!destroy_in_thread) {
                __gsource_remove_and_destroy(source);
        }
+
        g_mutex_unlock(&thread->thread_mutex);
 }
 
index 6debf26..365fead 100755 (executable)
@@ -2911,8 +2911,14 @@ __thread_func_waiting_source_dispatch(tpl_gsource *gsource, uint64_t message)
 {
        tpl_wl_egl_buffer_t *wl_egl_buffer      =
                (tpl_wl_egl_buffer_t *)tpl_gsource_get_data(gsource);
+       TPL_CHECK_ON_NULL_RETURN_VAL(wl_egl_buffer, TPL_FALSE);
+
        tpl_wl_egl_surface_t *wl_egl_surface    = wl_egl_buffer->wl_egl_surface;
+       TPL_CHECK_ON_NULL_RETURN_VAL(wl_egl_surface, TPL_FALSE);
+
        tbm_surface_h tbm_surface               = wl_egl_buffer->tbm_surface;
+       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++;
 
@@ -2929,7 +2935,6 @@ __thread_func_waiting_source_dispatch(tpl_gsource *gsource, uint64_t message)
                          wl_egl_surface, wl_egl_buffer, wl_egl_buffer->waiting_source,
                          wl_egl_buffer->acquire_fence_fd);
 
-       close(wl_egl_buffer->acquire_fence_fd);
        wl_egl_buffer->acquire_fence_fd = -1;
        wl_egl_buffer->waiting_source = NULL;
 
@@ -3732,6 +3737,7 @@ __cb_wl_egl_buffer_free(tpl_wl_egl_buffer_t *wl_egl_buffer)
                wl_egl_buffer->num_rects = 0;
        }
 
+       wl_egl_buffer->wl_egl_surface = NULL;
        wl_egl_buffer->tbm_surface = NULL;
        wl_egl_buffer->bo_name = -1;
        wl_egl_buffer->status = RELEASED;