tpl_wayland_egl_thread: Added APIs for thread safety during event processing. 72/135172/4
authorjoonbum.ko <joonbum.ko@samsung.com>
Thu, 25 May 2017 04:27:16 +0000 (13:27 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Thu, 22 Jun 2017 08:55:59 +0000 (08:55 +0000)
 - 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 <joonbum.ko@samsung.com>
src/tpl_wayland_egl_thread.c
src/tpl_wayland_egl_thread.h

index d363d18..d9f0884 100644 (file)
@@ -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);
 
index 619f583..424a539 100644 (file)
@@ -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,