From 4ccde4f77495cf1256847582cfbc25cc977d3ca4 Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Tue, 5 Apr 2016 21:16:50 +0900 Subject: [PATCH] ecore_wl: use wl_display_prepare_read() before poll() 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 | 50 +++++++++++++++++++++++++++----- src/lib/ecore_wayland/ecore_wl_private.h | 2 ++ 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/lib/ecore_wayland/ecore_wl.c b/src/lib/ecore_wayland/ecore_wl.c index 586d373..1d5705f 100644 --- a/src/lib/ecore_wayland/ecore_wl.c +++ b/src/lib/ecore_wayland/ecore_wl.c @@ -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 diff --git a/src/lib/ecore_wayland/ecore_wl_private.h b/src/lib/ecore_wayland/ecore_wl_private.h index a0d6e12..5823b5d 100644 --- a/src/lib/ecore_wayland/ecore_wl_private.h +++ b/src/lib/ecore_wayland/ecore_wl_private.h @@ -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; -- 2.7.4