maxfds = (ecore_fds >= glib_fds) ? ecore_fds : glib_fds;
ret = _ecore_glib_select_original(maxfds, rfds, wfds, efds, timeout);
+ //TIZEN_ONLY: ecore: stabilize wayland event handling in multithread
+ /* 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
(_ecore_glib_fds, reqfds, rfds, wfds, efds, ret);
// for legacy mainloop only and not other loops
int in_main_loop = 0;
+
+//TIZEN_ONLY: ecore: stabilize wayland event handling in multithread
+static Eina_Bool need_fdh_mark_active = EINA_FALSE;
+static Eina_List *awake_funcs = NULL;
+//
+
#ifndef USE_G_MAIN_LOOP
static double t1 = 0.0;
static double t2 = 0.0;
}
#endif
+//TIZEN_ONLY: ecore: stabilize wayland event handling in multithread
+int
+_ecore_main_fdh_mark_active(fd_set *rfds, fd_set *wfds, fd_set *exfds)
+{
+ Ecore_Fd_Handler *fdh;
+ Eina_List *l;
+ int ret = 0;
+
+ need_fdh_mark_active = EINA_FALSE;
+
+#ifdef HAVE_EPOLL
+ if (HAVE_EPOLL && epoll_fd >= 0)
+ ret = _ecore_main_fdh_epoll_mark_active();
+ else
+#endif
+ {
+ EINA_INLIST_FOREACH(fd_handlers, fdh)
+ {
+ if (!fdh->delete_me)
+ {
+ if (FD_ISSET(fdh->fd, rfds))
+ fdh->read_active = EINA_TRUE;
+ if (FD_ISSET(fdh->fd, wfds))
+ fdh->write_active = EINA_TRUE;
+ if (FD_ISSET(fdh->fd, exfds))
+ fdh->error_active = EINA_TRUE;
+ _ecore_try_add_to_call_list(fdh);
+ if (fdh->read_active || fdh->write_active || fdh->error_active)
+ ret++;
+ }
+ }
+ }
+ EINA_LIST_FOREACH(file_fd_handlers, l, fdh)
+ {
+ if (!fdh->delete_me)
+ {
+ if (FD_ISSET(fdh->fd, rfds))
+ fdh->read_active = EINA_TRUE;
+ if (FD_ISSET(fdh->fd, wfds))
+ fdh->write_active = EINA_TRUE;
+ if (FD_ISSET(fdh->fd, exfds))
+ fdh->error_active = EINA_TRUE;
+ _ecore_try_add_to_call_list(fdh);
+ if (fdh->read_active || fdh->write_active || fdh->error_active)
+ ret++;
+ }
+ }
+
+ return ret;
+}
+//
+
#ifdef USE_G_MAIN_LOOP
static inline int
_ecore_main_fdh_glib_mark_active(Eo *obj, Efl_Loop_Data *pd)
return main_loop_select;
}
+//TIZEN_ONLY: ecore: stabilize wayland event handling in multithread
+EAPI Eina_Bool
+ecore_main_awake_handler_add(Ecore_Awake_Cb func, void *data)
+{
+ Ecore_Awake_Handler *handler;
+
+ if (!func) return EINA_FALSE;
+
+ handler = calloc(1, sizeof *handler);
+ if (!handler) return EINA_FALSE;
+
+ handler->func = func;
+ handler->data = (void*)data;
+ awake_funcs = eina_list_append(awake_funcs, handler);
+
+ return EINA_TRUE;
+}
+
+EAPI void
+ecore_main_awake_handler_del(Ecore_Awake_Cb func)
+{
+ Ecore_Awake_Handler *handler;
+ Eina_List *l, *ll;
+
+ if (!func) return;
+
+ EINA_LIST_FOREACH_SAFE(awake_funcs, l, ll, handler)
+ {
+ if (handler->func != func)
+ continue;
+
+ awake_funcs = eina_list_remove(awake_funcs, handler);
+ free(handler);
+ break;
+ }
+}
+
+void
+_ecore_main_awake_handler_call(void)
+{
+ Ecore_Awake_Handler *handler;
+ Eina_List *l, *ll;
+
+ EINA_LIST_FOREACH_SAFE(awake_funcs, l, ll, handler)
+ {
+ if (handler->func)
+ handler->func(handler->data);
+ }
+}
+//
+
Ecore_Fd_Handler *
_ecore_main_fd_handler_add(Eo *obj,
Efl_Loop_Data *pd,
pd->do_quit = 0;
+ //TIZEN_ONLY: ecore: stabilize wayland event handling in multithread
+ if (awake_funcs)
+ awake_funcs = eina_list_free(awake_funcs);
+ //
+
+
#ifdef _WIN32
while (pd->win32_handlers)
{
}
if (_ecore_signal_count_get(obj, pd)) return -1;
+ //TIZEN_ONLY: ecore: stabilize wayland event handling in multithread
+ need_fdh_mark_active = EINA_TRUE;
+ //
+
eina_evlog("<RUN", NULL, 0.0, NULL);
eina_evlog("!SLEEP", NULL, 0.0, t ? "timeout" : "forever");
if (obj == ML_OBJ)
}
if (ret > 0)
{
+ //TIZEN_ONLY: ecore: stabilize wayland event handling in multithread
+ /*
#ifdef HAVE_EPOLL
if (pd->epoll_fd >= 0)
_ecore_main_fdh_epoll_mark_active(obj, pd);
_ecore_try_add_to_call_list(obj, pd, fdh);
}
}
+ */
+ if (need_fdh_mark_active)
+ {
+ _ecore_main_fdh_mark_active(&rfds, &wfds, &exfds);
+ _ecore_main_awake_handler_call();
+ }
+ //
+
_ecore_main_fd_handlers_cleanup(obj, pd);
#ifdef _WIN32
_ecore_main_win32_handlers_cleanup(obj, pd);