ecore_wl: use wl_display_prepare_read() before poll() 20/64820/5 accepted/tizen/common/20160408.184957 accepted/tizen/ivi/20160408.052644 accepted/tizen/mobile/20160408.052702 accepted/tizen/tv/20160408.052620 accepted/tizen/wearable/20160408.052636 submit/tizen/20160408.022044
authorSangjin Lee <lsj119@samsung.com>
Tue, 5 Apr 2016 12:16:50 +0000 (21:16 +0900)
committerSangjin Lee <lsj119@samsung.com>
Fri, 8 Apr 2016 01:33:35 +0000 (10:33 +0900)
For thread-safety, wayland recommend use this function before wait using poll()
Please see documentation of wl_displau_repare_read_queue()
https://wayland.freedesktop.org/docs/html/apb.html#Client-classwl__display_1a40039c1169b153269a3dc0796a54ddb0

Change-Id: I0d01952433f746abf445928078d8124ca8d327b0

src/lib/ecore_wayland/ecore_wl.c
src/lib/ecore_wayland/ecore_wl_private.h

index 586d373..1d5705f 100644 (file)
@@ -26,6 +26,7 @@
 static int _ecore_wl_shutdown(Eina_Bool close);
 static Eina_Bool _ecore_wl_cb_idle_enterer(void *data);
 static Eina_Bool _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl);
+static void _ecore_wl_cb_pre_handle_data(void *data, Ecore_Fd_Handler *hdl);
 static void _ecore_wl_cb_handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version EINA_UNUSED);
 static void _ecore_wl_cb_handle_global_remove(void *data, struct wl_registry *registry EINA_UNUSED, unsigned int id);
 static Eina_Bool _ecore_wl_xkb_init(Ecore_Wl_Display *ewd);
@@ -110,7 +111,7 @@ static const struct tizen_effect_listener _ecore_tizen_effect_listener =
    _ecore_wl_cb_effect_end,
 };
 
-static void 
+static void
 xdg_shell_ping(void *data EINA_UNUSED, struct xdg_shell *shell, uint32_t serial)
 {
    xdg_shell_pong(shell, serial);
@@ -273,6 +274,9 @@ ecore_wl_init(const char *name)
                                ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ERROR,
                                _ecore_wl_cb_handle_data, _ecore_wl_disp,
                                NULL, NULL);
+   ecore_main_fd_handler_prepare_callback_set(_ecore_wl_disp->fd_hdl,
+                                              _ecore_wl_cb_pre_handle_data,
+                                              _ecore_wl_disp);
 
    _ecore_wl_disp->idle_enterer =
      ecore_idle_enterer_add(_ecore_wl_cb_idle_enterer, _ecore_wl_disp);
@@ -342,7 +346,6 @@ ecore_wl_flush(void)
 EAPI void
 ecore_wl_sync(void)
 {
-
    int ret;
    if ((!_ecore_wl_disp) || (!_ecore_wl_disp->wl.display)) return;
    _ecore_wl_sync_wait(_ecore_wl_disp);
@@ -734,19 +737,23 @@ _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl)
         _ecore_wl_fatal_error = EINA_TRUE;
         _ecore_wl_signal_exit();
 
-        return ECORE_CALLBACK_CANCEL;
+        goto cancel_read;
      }
 
-   /* wl_display_dispatch_pending(ewd->wl.display); */
-
    if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
-     ret = wl_display_dispatch(ewd->wl.display);
+     {
+        wl_display_read_events(ewd->wl.display);
+        ret = wl_display_dispatch_pending(ewd->wl.display);
+     }
    else if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
      {
         ret = wl_display_flush(ewd->wl.display);
         if (ret == 0)
-          ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
+           ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
+        wl_display_cancel_read(ewd->wl.display);
      }
+   else
+        goto cancel_read;
 
    if ((ret < 0) && ((errno != EAGAIN) && (errno != EINVAL)))
      {
@@ -755,10 +762,37 @@ _ecore_wl_cb_handle_data(void *data, Ecore_Fd_Handler *hdl)
         /* raise exit signal */
         _ecore_wl_signal_exit();
 
-        return ECORE_CALLBACK_CANCEL;
+        goto cancel_read;
      }
 
+   ewd->wl.prepare_read = EINA_FALSE;
    return ECORE_CALLBACK_RENEW;
+
+cancel_read:
+   wl_display_cancel_read(ewd->wl.display);
+   ewd->wl.prepare_read = EINA_FALSE;
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_ecore_wl_cb_pre_handle_data(void *data, Ecore_Fd_Handler *hdl EINA_UNUSED)
+{
+   Ecore_Wl_Display *ewd;
+
+   if (_ecore_wl_fatal_error) return;
+
+   if (!(ewd = data)) return;
+
+   if (ewd->wl.prepare_read) return;
+
+   while (wl_display_prepare_read(ewd->wl.display) != 0)
+     {
+        wl_display_dispatch_pending(ewd->wl.display);
+     }
+   wl_display_flush(ewd->wl.display);
+
+   ewd->wl.prepare_read = EINA_TRUE;
 }
 
 static void
index a0d6e12..5823b5d 100644 (file)
@@ -100,6 +100,8 @@ struct _Ecore_Wl_Display
         struct tizen_keyrouter *keyrouter;
         struct tizen_input_device_manager *tz_input_device_manager;
         struct tizen_effect *tz_effect;
+
+        Eina_Bool prepare_read;
      } wl;
 
    int fd;