From c3062c0e0f8d5cf1828c8defbb864bd382ae76ec Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 25 May 2017 13:27:16 +0900 Subject: [PATCH] tpl_wayland_egl_thread: Added APIs for thread safety during event processing. - If a new event is handled in the worker_thread while processing the dequeue process in the main thread, it can cause problems. - Thread safety must be guaranteed in the part that uses the same resource (tbm_surface_queue) between threads. - Added APIs twe_display_lock / twe_display_unlock Change-Id: I3cd405147a196ced800faefec80e559b15693673 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 43 ++++++++++++++++++++++++++++++++++++++++--- src/tpl_wayland_egl_thread.h | 6 ++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index d363d18..d9f0884 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -50,6 +50,7 @@ struct _twe_wl_disp_source { struct wayland_tbm_client *wl_tbm_client; struct tizen_surface_shm *tss; /* used for surface buffer_flush */ twe_thread *thread; + tpl_object_t obj; /* TODO : surface list */ }; @@ -286,6 +287,7 @@ _twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer date) return G_SOURCE_REMOVE; } + TPL_OBJECT_LOCK(&disp_source->obj); if (disp_source->gfd.revents & G_IO_IN) { if (wl_display_dispatch_queue_pending(disp_source->disp, disp_source->ev_queue) == -1) { @@ -294,6 +296,7 @@ _twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer date) } wl_display_flush(disp_source->disp); + TPL_OBJECT_UNLOCK(&disp_source->obj); return G_SOURCE_CONTINUE; } @@ -303,12 +306,16 @@ _twe_thread_wl_disp_finalize(GSource *source) { twe_wl_disp_source *disp_source = (twe_wl_disp_source *)source; + TPL_OBJECT_LOCK(&disp_source->obj); if (wl_display_dispatch_queue_pending(disp_source->disp, disp_source->ev_queue) == -1) { _twe_display_print_err(disp_source, "dispatch_queue_pending"); } wl_event_queue_destroy(disp_source->ev_queue); + TPL_OBJECT_UNLOCK(&disp_source->obj); + + __tpl_object_fini(&disp_source->obj); TPL_LOG_T("WL_EGL", "finalize| wl_event_queue(%p)", disp_source->ev_queue); @@ -474,6 +481,7 @@ twe_display_add(twe_thread* thread, struct wl_display *display) source->gfd.fd = wl_display_get_fd(display); source->gfd.events = G_IO_IN | G_IO_ERR; source->gfd.revents = 0; + __tpl_object_init(&source->obj, TPL_OBJECT_DISPLAY, NULL); _twe_display_shm_init(source); @@ -518,6 +526,30 @@ twe_display_del(twe_display_h twe_display) return TPL_ERROR_NONE; } +tpl_result_t +twe_display_lock(twe_display_h display) +{ + twe_wl_disp_source *disp_source = (twe_wl_disp_source *)display; + if (!disp_source || g_source_is_destroyed(&disp_source->gsource)) { + TPL_ERR("Invalid parameter. display(%p)", display); + return TPL_ERROR_INVALID_PARAMETER; + } + + return TPL_OBJECT_LOCK(&disp_source->obj); +} + +void +twe_display_unlock(twe_display_h display) +{ + twe_wl_disp_source *disp_source = (twe_wl_disp_source *)display; + if (!disp_source || g_source_is_destroyed(&disp_source->gsource)) { + TPL_ERR("Invalid parameter. display(%p)", display); + return; + } + + TPL_OBJECT_UNLOCK(&disp_source->obj); +} + static void __cb_resize_callback(struct wl_egl_window *wl_egl_window, void *private) { @@ -588,12 +620,14 @@ static void __cb_tss_flusher_flush_callback(void *data, - dispatch buffer-release - dispatch queue flush */ + TPL_OBJECT_LOCK(&disp_source->obj); ret = wl_display_dispatch_queue_pending(disp_source->disp, disp_source->ev_queue); if (ret == -1) { _twe_display_print_err(disp_source, "dispatch_queue_pending"); return; } + TPL_OBJECT_UNLOCK(&disp_source->obj); tbm_surface_queue_flush(surf_source->tbm_queue); @@ -1222,9 +1256,6 @@ twe_surface_del(twe_surface_h twe_surface) return TPL_ERROR_INVALID_PARAMETER; } - TPL_LOG_T("WL_EGL", "twe_surface(%p) wl_egl_window(%p) wl_surface(%p)", - surf_source, surf_source->wl_egl_window, surf_source->surf); - /* Should be waited until all in_use_buffers has been retrieved. */ while (!__tpl_list_is_empty(surf_source->in_use_buffers)) { sched_yield(); @@ -1233,6 +1264,7 @@ twe_surface_del(twe_surface_h twe_surface) __tpl_list_free(surf_source->in_use_buffers, NULL); surf_source->in_use_buffers = NULL; + TPL_OBJECT_LOCK(&disp_source->obj); if (surf_source->committed_buffers) { TPL_OBJECT_LOCK(&surf_source->obj); while (!__tpl_list_is_empty(surf_source->committed_buffers)) { @@ -1263,9 +1295,14 @@ twe_surface_del(twe_surface_h twe_surface) /* TODO : surf_source will be removed from surfaces list in disp_source */ + TPL_LOG_T("WL_EGL", "twe_surface(%p) wl_egl_window(%p) wl_surface(%p)", + surf_source, surf_source->wl_egl_window, surf_source->surf); + surf_source->wl_egl_window = NULL; surf_source->surf = NULL; + TPL_OBJECT_UNLOCK(&disp_source->obj); + g_source_destroy(&surf_source->gsource); g_source_unref(&surf_source->gsource); diff --git a/src/tpl_wayland_egl_thread.h b/src/tpl_wayland_egl_thread.h index 619f583..424a539 100644 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -22,6 +22,12 @@ twe_display_add(twe_thread* thread, struct wl_display *display); tpl_result_t twe_display_del(twe_display_h display); +tpl_result_t +twe_display_lock(twe_display_h display); + +void +twe_display_unlock(twe_display_h display); + twe_surface_h twe_surface_add(twe_thread* thread, twe_display_h twe_display, -- 2.7.4