ecore_glib: marking active only if there are events to handle 12/155612/6
authorBoram Park <boram1288.park@samsung.com>
Sun, 15 Oct 2017 10:02:57 +0000 (19:02 +0900)
committerBoram Park <boram1288.park@samsung.com>
Mon, 16 Oct 2017 01:20:59 +0000 (10:20 +0900)
If select() returns 0, we expact rfds doesn't contains any fds. But even if
select() returns 0, rfds sometimes contains a wayland fd. It makes wrong
behavior.

Once exit from select(), _ecore_main_awake_handler_call() should be called here
to call wl_display_cancel_read() or wl_display_read_events().
If not, deadlock can occur when g_main_context_dispatch calls a user callback
and a user callback calls wl_display_roundtrip which make read_count +2 in one
thread. Moreover, if the main thread sleeps to wait for the some events in
g_main_context_dispatch() or _ecore_idle_enterer_call() function, and if another
thread calls prepare_read(), deadlock also can occur in main thread because main
thread has slept to wait for something and it can't call read_event() or
cancel_event().

Change-Id: Ia786ba2b7c525611be7d0ab9036581e812ce3a2f

src/lib/ecore/ecore_glib.c

index b52c032..5535904 100644 (file)
@@ -168,7 +168,22 @@ _ecore_glib_select__locked(GMainContext   *ctx,
    maxfds = (ecore_fds >= glib_fds) ? ecore_fds : glib_fds;
    ret = _ecore_glib_select_original(maxfds, rfds, wfds, efds, timeout);
 
-   _ecore_main_fdh_mark_active(rfds, wfds, efds);
+   /* If select() returns 0, we expact rfds doesn't contains any fds. But even if
+    * select() returns 0, rfds sometimes contains a wayland fd. It makes wrong
+    * behavior.
+    */
+   if (ret > 0)
+     _ecore_main_fdh_mark_active(rfds, wfds, efds);
+
+   /* Once exit from select(), _ecore_main_awake_handler_call() should be called here
+    * to call wl_display_cancel_read() or wl_display_read_events().
+    * If not, deadlock can occur when g_main_context_dispatch calls a user callback
+    * and a user callback calls wl_display_roundtrip which make read_count +2 in one
+    * thread. Moreover, if the main thread sleeps to wait for the some events in
+    * g_main_context_dispatch() or _ecore_idle_enterer_call() function, and if another
+    * thread calls prepare_read(), deadlock also can occur in main thread because main
+    * thread sleeps and it can't call read_event() or cancel_event().
+    */
    _ecore_main_awake_handler_call();
 
    ret = _ecore_glib_context_poll_to