diff options
Diffstat (limited to 'src/lib/ecore/ecore_main.c')
-rw-r--r-- | src/lib/ecore/ecore_main.c | 3221 |
1 files changed, 1338 insertions, 1883 deletions
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c index 6a5ea42def..59631892e7 100644 --- a/src/lib/ecore/ecore_main.c +++ b/src/lib/ecore/ecore_main.c @@ -25,7 +25,7 @@ #endif #ifdef HAVE_IEEEFP_H -# include <ieeefp.h> /* for Solaris */ +# include <ieeefp.h> // for Solaris #endif #ifdef _MSC_VER @@ -60,120 +60,31 @@ #include "Ecore.h" #include "ecore_private.h" -#if defined(HAVE_SYS_EPOLL_H) && !defined(HAVE_LIBUV) -# define HAVE_EPOLL 1 -# include <sys/epoll.h> -#else - -# define HAVE_EPOLL 0 -# define EPOLLIN 1 -# define EPOLLPRI 2 -# define EPOLLOUT 4 -# define EPOLLERR 8 - -#define EPOLL_CTL_ADD 1 -#define EPOLL_CTL_DEL 2 -#define EPOLL_CTL_MOD 3 - -typedef union epoll_data { - void *ptr; - int fd; - uint32_t u32; - uint64_t u64; -} epoll_data_t; - -struct epoll_event -{ - uint32_t events; - epoll_data_t data; -}; - -static inline int -epoll_create(int size EINA_UNUSED) -{ - return -1; -} - -static inline int -epoll_wait(int epfd EINA_UNUSED, - struct epoll_event *events EINA_UNUSED, - int maxevents EINA_UNUSED, - int timeout EINA_UNUSED) -{ - return -1; -} - -static inline int -epoll_ctl(int epfd EINA_UNUSED, - int op EINA_UNUSED, - int fd EINA_UNUSED, - struct epoll_event *event EINA_UNUSED) -{ - return -1; -} - -#endif - -#ifdef HAVE_SYS_TIMERFD_H -# include <sys/timerfd.h> -#else -/* fallback code if we don't have real timerfd - reduces number of ifdefs */ -# ifndef CLOCK_MONOTONIC -# define CLOCK_MONOTONIC 0 /* bogus value */ -# endif -# ifndef TFD_NONBLOCK -# define TFD_NONBLOCK 0 /* bogus value */ -# endif -#endif /* HAVE_SYS_TIMERFD_H */ - -#ifndef TFD_TIMER_ABSTIME -# define TFD_TIMER_ABSTIME (1 << 0) -#endif -#ifndef TFD_TIMER_CANCELON_SET -# define TFD_TIMER_CANCELON_SET (1 << 1) -#endif - -#ifndef HAVE_TIMERFD_CREATE -static inline int -timerfd_create(int clockid EINA_UNUSED, - int flags EINA_UNUSED) -{ - return -1; -} - -static inline int -timerfd_settime(int fd EINA_UNUSED, - int flags EINA_UNUSED, - const struct itimerspec *new_value EINA_UNUSED, - struct itimerspec *old_value EINA_UNUSED) -{ - return -1; -} - -#endif /* HAVE_TIMERFD_CREATE */ +#include "ecore_main_common.h" #ifdef USE_G_MAIN_LOOP # include <glib.h> #endif #ifdef HAVE_LIBUV -#ifdef HAVE_NODE_UV_H -#include <node/uv.h> -#elif defined(HAVE_NODEJS_DEPS_UV_UV_H) -#include <nodejs/deps/uv/uv.h> -#elif defined(HAVE_NODEJS_DEPS_UV_INCLUDE_UV_H) -#include <nodejs/deps/uv/include/uv.h> -#elif defined(HAVE_NODEJS_SRC_UV_H) -#include <nodejs/src/uv.h> -#elif defined(HAVE_UV_H) -#include <uv.h> -#else -#error No uv.h header found? -#endif +# ifdef HAVE_NODE_UV_H +# include <node/uv.h> +# elif defined(HAVE_NODEJS_DEPS_UV_UV_H) +# include <nodejs/deps/uv/uv.h> +# elif defined(HAVE_NODEJS_DEPS_UV_INCLUDE_UV_H) +# include <nodejs/deps/uv/include/uv.h> +# elif defined(HAVE_NODEJS_SRC_UV_H) +# include <nodejs/src/uv.h> +# elif defined(HAVE_UV_H) +# include <uv.h> +# else +# error No uv.h header found? +# endif -#if defined HAVE_DLOPEN && ! defined _WIN32 -# include <dlfcn.h> -#endif +// XXX: FIXME: use eina_module +# if defined(HAVE_DLOPEN) && !defined(_WIN32) +# include <dlfcn.h> +# endif static uv_prepare_t _ecore_main_uv_prepare; static uv_check_t _ecore_main_uv_check; @@ -203,73 +114,70 @@ static int (*_dl_uv_check_stop)(uv_check_t* prepare); static int (*_dl_uv_close)(uv_handle_t* handle, uv_close_cb close_cb); #endif -#define NS_PER_SEC (1000.0 * 1000.0 * 1000.0) +#define NS_PER_SEC (1000000000.0) struct _Ecore_Fd_Handler { EINA_INLIST; - ECORE_MAGIC; - Ecore_Fd_Handler *next_ready; - int fd; - Ecore_Fd_Handler_Flags flags; - Ecore_Fd_Cb func; - void *data; - Ecore_Fd_Cb buf_func; - void *buf_data; - Ecore_Fd_Prep_Cb prep_func; - void *prep_data; - int references; - Eina_Bool read_active : 1; - Eina_Bool write_active : 1; - Eina_Bool error_active : 1; - Eina_Bool delete_me : 1; - Eina_Bool file : 1; + ECORE_MAGIC; + Ecore_Fd_Handler *next_ready; + int fd; + Ecore_Fd_Handler_Flags flags; + Eo *handler; + Eo *loop; + Efl_Loop_Data *loop_data; + Ecore_Fd_Cb func; + void *data; + Ecore_Fd_Cb buf_func; + void *buf_data; + Ecore_Fd_Prep_Cb prep_func; + void *prep_data; + int references; #if defined(USE_G_MAIN_LOOP) - GPollFD gfd; + GPollFD gfd; #endif #ifdef HAVE_LIBUV - uv_poll_t uv_handle; + uv_poll_t uv_handle; #endif + Eina_Bool read_active : 1; + Eina_Bool write_active : 1; + Eina_Bool error_active : 1; + Eina_Bool delete_me : 1; + Eina_Bool file : 1; }; GENERIC_ALLOC_SIZE_DECLARE(Ecore_Fd_Handler); -typedef struct _Efl_Loop_Promise_Simple_Data { - union { - Ecore_Timer *timer; - Ecore_Idler *idler; - }; - Eina_Promise *promise; -} Efl_Loop_Promise_Simple_Data; -GENERIC_ALLOC_SIZE_DECLARE(Efl_Loop_Promise_Simple_Data); - #ifdef _WIN32 struct _Ecore_Win32_Handler { EINA_INLIST; - ECORE_MAGIC; - HANDLE h; - Ecore_Win32_Handle_Cb func; - void *data; - int references; - Eina_Bool delete_me : 1; + ECORE_MAGIC; + HANDLE h; + Eo *handler; + Eo *loop; + Efl_Loop_Data *loop_data; + Ecore_Win32_Handle_Cb func; + void *data; + int references; + Eina_Bool delete_me : 1; }; GENERIC_ALLOC_SIZE_DECLARE(Ecore_Win32_Handler); #endif #if !defined(USE_G_MAIN_LOOP) && !defined(HAVE_LIBUV) -static int _ecore_main_select(double timeout); +static int _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout); #endif -static void _ecore_main_prepare_handlers(void); -static void _ecore_main_fd_handlers_cleanup(void); +static void _ecore_main_prepare_handlers(Eo *obj, Efl_Loop_Data *pd); +static void _ecore_main_fd_handlers_cleanup(Eo *obj, Efl_Loop_Data *pd); #ifndef _WIN32 # ifndef USE_G_MAIN_LOOP -static void _ecore_main_fd_handlers_bads_rem(void); +static void _ecore_main_fd_handlers_bads_rem(Eo *obj, Efl_Loop_Data *pd); # endif #endif -static void _ecore_main_fd_handlers_call(void); -static int _ecore_main_fd_handlers_buf_call(void); +static void _ecore_main_fd_handlers_call(Eo *obj, Efl_Loop_Data *pd); +static int _ecore_main_fd_handlers_buf_call(Eo *obj, Efl_Loop_Data *pd); #ifndef USE_G_MAIN_LOOP -static void _ecore_main_loop_iterate_internal(int once_only); +static void _ecore_main_loop_iterate_internal(Eo *obj, Efl_Loop_Data *pd, int once_only); #endif #ifdef _WIN32 @@ -278,127 +186,96 @@ static int _ecore_main_win32_select(int nfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); -static void _ecore_main_win32_handlers_cleanup(void); -#endif - -int in_main_loop = 0; - -static Eina_List *_pending_futures = NULL; -static Eina_List *_pending_promises = NULL; -#if (defined __GNUC__) && (__GNUC__ <= 4) -// GCC 4 does not support compound literal for statics initializers in C99 -static Eina_Value _ecore_exit_code = {0}; -# else -static Eina_Value _ecore_exit_code = EINA_VALUE_EMPTY; -#endif -static int do_quit = 0; -static Ecore_Fd_Handler *fd_handlers = NULL; -static Ecore_Fd_Handler *fd_handler_current = NULL; -static Eina_List *fd_handlers_with_prep = NULL; -static Eina_List *file_fd_handlers = NULL; -static Eina_List *fd_handlers_with_buffer = NULL; -static Eina_List *fd_handlers_to_delete = NULL; - -/* single linked list of ready fdhs, terminated by loop to self */ -static Ecore_Fd_Handler *fd_handlers_to_call; -static Ecore_Fd_Handler *fd_handlers_to_call_current; - -#ifdef _WIN32 -static Ecore_Win32_Handler *win32_handlers = NULL; -static Ecore_Win32_Handler *win32_handler_current = NULL; -static Eina_List *win32_handlers_to_delete = NULL; +static void _ecore_main_win32_handlers_cleanup(Eo *obj, Efl_Loop_Data *pd); #endif -#ifdef _WIN32 -Ecore_Select_Function main_loop_select = _ecore_main_win32_select; -#else -# if !defined EXOTIC_NO_SELECT -# include <sys/select.h> -Ecore_Select_Function main_loop_select = select; -# else -Ecore_Select_Function main_loop_select = NULL; -# endif -#endif +static void _ecore_main_loop_setup(Eo *obj, Efl_Loop_Data *pd); +static void _ecore_main_loop_clear(Eo *obj, Efl_Loop_Data *pd); +// for legacy mainloop only and not other loops +int in_main_loop = 0; #ifndef USE_G_MAIN_LOOP static double t1 = 0.0; static double t2 = 0.0; #endif -#ifdef HAVE_EPOLL -static int epoll_fd = -1; -static pid_t epoll_pid; +#ifdef _WIN32 +Ecore_Select_Function main_loop_select = _ecore_main_win32_select; +static Ecore_Select_Function general_loop_select = _ecore_main_win32_select; +#else +# include <sys/select.h> +Ecore_Select_Function main_loop_select = select; +static Ecore_Select_Function general_loop_select = select; #endif -static int timer_fd = -1; #ifdef USE_G_MAIN_LOOP -static GPollFD ecore_epoll_fd; -static GPollFD ecore_timer_fd; -static GSource *ecore_glib_source; -static guint ecore_glib_source_id; +static GPollFD ecore_epoll_fd; +static GPollFD ecore_timer_fd; +static GSource *ecore_glib_source; +static guint ecore_glib_source_id; static GMainLoop *ecore_main_loop; -static gboolean ecore_idling; -static gboolean _ecore_glib_idle_enterer_called; -static gboolean ecore_fds_ready; +static gboolean ecore_idling; +static gboolean _ecore_glib_idle_enterer_called; +static gboolean ecore_fds_ready; #endif #ifdef EFL_EXTRA_SANITY_CHECKS static inline void -_ecore_fd_valid(void) +_ecore_fd_valid(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) { -#ifdef HAVE_EPOLL - if (epoll_fd >= 0) +# ifdef HAVE_EPOLL + if ((pd->epoll_fd >= 0) && + (fcntl(pd->epoll_fd, F_GETFD) < 0)) { - if (fcntl(epoll_fd, F_GETFD) < 0) - { - ERR("arghhh you caught me! report a backtrace to edevel!"); -#ifdef HAVE_PAUSE - pause(); -#else - sleep(60); -#endif - } + ERR("arghhh you caught me! report a backtrace to edevel!"); +# ifdef HAVE_PAUSE + pause(); +# else + sleep(60); +# endif } -#endif +# endif } #endif static inline void -_ecore_try_add_to_call_list(Ecore_Fd_Handler *fdh) +_ecore_try_add_to_call_list(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, Ecore_Fd_Handler *fdh) { - /* check if this fdh is already in the list */ + // check if this fdh is already in the list if (fdh->next_ready) { - DBG("next_ready"); - return; + DBG("next_ready"); + return; } if (fdh->read_active || fdh->write_active || fdh->error_active) { - DBG("added"); - /* - * make sure next_ready is non-null by pointing to ourselves - * use that to indicate this fdh is in the ready list - * insert at the head of the list to avoid trouble - */ - fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh; - fd_handlers_to_call = fdh; + DBG("added"); + // make sure next_ready is non-null by pointing to ourselves + // use that to indicate this fdh is in the ready list + // insert at the head of the list to avoid trouble + fdh->next_ready = pd->fd_handlers_to_call ? pd->fd_handlers_to_call : fdh; + pd->fd_handlers_to_call = fdh; } } +static inline void +_throttle_do(Efl_Loop_Data *pd) +{ + if (pd->throttle == 0) return + eina_evlog("+throttle", NULL, 0.0, NULL); + usleep(pd->throttle); + eina_evlog("-throttle", NULL, 0.0, NULL); +} + #ifdef HAVE_EPOLL static inline int -_ecore_get_epoll_fd(void) +_ecore_get_epoll_fd(Eo *obj, Efl_Loop_Data *pd) { - if (epoll_pid && (epoll_pid != getpid())) - { - /* forked! */ - _ecore_main_loop_shutdown(); - } - if ((epoll_pid == 0) && (epoll_fd < 0)) - { - _ecore_main_loop_init(); - } - return epoll_fd; + if (pd->epoll_pid && (pd->epoll_pid != getpid())) // forked! + _ecore_main_loop_clear(obj, pd); + if ((pd->epoll_pid == 0) && (pd->epoll_fd < 0)) + _ecore_main_loop_setup(obj, pd); + return pd->epoll_fd; } static inline int @@ -420,7 +297,7 @@ static inline int _ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh) { int events = 0; - if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN; + if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN; if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT; if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR | EPOLLPRI; return events; @@ -432,7 +309,7 @@ static inline int _gfd_events_from_fdh(Ecore_Fd_Handler *fdh) { int events = 0; - if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN; + if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN; if (fdh->flags & ECORE_FD_WRITE) events |= G_IO_OUT; if (fdh->flags & ECORE_FD_ERROR) events |= G_IO_ERR; return events; @@ -441,42 +318,42 @@ _gfd_events_from_fdh(Ecore_Fd_Handler *fdh) #ifdef HAVE_LIBUV static void -_ecore_main_uv_poll_cb(uv_poll_t* handle, int status, int events) +_ecore_main_uv_poll_cb(uv_poll_t *handle, int status, int events) { - DBG("_ecore_main_uv_poll_cb %p status %d events %d", (void*)handle->data, status, events); - Ecore_Fd_Handler* fdh = handle->data; + Eo *obj = ML_OBJ; + Efl_Loop_Data *pd = ML_DAT; - if(_ecore_main_uv_idling) + DBG("_ecore_main_uv_poll_cb %p status %d events %d", + (void *)handle->data, status, events); + Ecore_Fd_Handler *fdh = handle->data; + + if (_ecore_main_uv_idling) { DBG("not IDLE anymore"); _ecore_main_uv_idling = EINA_FALSE; - _ecore_idle_exiter_call(_mainloop_singleton); + _ecore_idle_exiter_call(obj); _ecore_animator_run_reset(); } - - if (status) - fdh->error_active = EINA_TRUE; - if (events & UV_READABLE) - fdh->read_active = EINA_TRUE; - if (events & UV_WRITABLE) - fdh->write_active = EINA_TRUE; - _ecore_try_add_to_call_list(fdh); + if (status) fdh->error_active = EINA_TRUE; + if (events & UV_READABLE) fdh->read_active = EINA_TRUE; + if (events & UV_WRITABLE) fdh->write_active = EINA_TRUE; + + _ecore_try_add_to_call_list(obj, pd, fdh); - _ecore_main_fd_handlers_call(); - if (fd_handlers_with_buffer) - _ecore_main_fd_handlers_buf_call(); - _ecore_signal_received_process(); - _ecore_event_call(); - _ecore_main_fd_handlers_cleanup(); - _efl_loop_timer_expired_timers_call(_ecore_time_loop_time); + _ecore_main_fd_handlers_call(obj, pd); + if (pd->fd_handlers_with_buffer) _ecore_main_fd_handlers_buf_call(obj, pd); + _ecore_signal_received_process(obj, pd); + efl_loop_message_process(obj); + _ecore_main_fd_handlers_cleanup(obj, pd); + _efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time); } static int _ecore_main_uv_events_from_fdh(Ecore_Fd_Handler *fdh) { int events = 0; - if (fdh->flags & ECORE_FD_READ) events |= UV_READABLE; + if (fdh->flags & ECORE_FD_READ) events |= UV_READABLE; if (fdh->flags & ECORE_FD_WRITE) events |= UV_WRITABLE; DBG("events is %d", (int)events); return events; @@ -484,50 +361,52 @@ _ecore_main_uv_events_from_fdh(Ecore_Fd_Handler *fdh) #endif static inline int -_ecore_main_fdh_poll_add(Ecore_Fd_Handler *fdh) +_ecore_main_fdh_poll_add(Efl_Loop_Data *pd EINA_UNUSED, Ecore_Fd_Handler *fdh) { DBG("_ecore_main_fdh_poll_add"); int r = 0; #ifdef HAVE_EPOLL -#ifdef HAVE_LIBUV - if(!_dl_uv_run) -#endif +# ifdef HAVE_LIBUV + if (!_dl_uv_run) +# endif { - if ((!fdh->file) && (epoll_fd >= 0)) - { - r = _ecore_epoll_add(_ecore_get_epoll_fd(), fdh->fd, - _ecore_poll_events_from_fdh(fdh), fdh); - } + if ((!fdh->file) && (pd->epoll_fd >= 0)) + r = _ecore_epoll_add(_ecore_get_epoll_fd(fdh->loop, pd), fdh->fd, + _ecore_poll_events_from_fdh(fdh), fdh); } -#ifdef HAVE_LIBUV +# ifdef HAVE_LIBUV else -#endif +# endif #endif { #ifdef HAVE_LIBUV - if(!fdh->file) - { - DBG("_ecore_main_fdh_poll_add libuv socket %p", fdh); - fdh->uv_handle.data = fdh; - DBG("_ecore_main_fdh_poll_add2 %p", fdh); - _dl_uv_poll_init_socket(_dl_uv_default_loop(), &fdh->uv_handle, fdh->fd); - DBG("_ecore_main_fdh_poll_add3 %p", fdh->uv_handle.data); - _dl_uv_poll_start(&fdh->uv_handle, _ecore_main_uv_events_from_fdh(fdh) - , _ecore_main_uv_poll_cb); - DBG("_ecore_main_fdh_poll_add libuv DONE"); - } - else - { - DBG("_ecore_main_fdh_poll_add libuv file"); - fdh->uv_handle.data = fdh; - DBG("_ecore_main_fdh_poll_add2 %p", fdh); - _dl_uv_poll_init(_dl_uv_default_loop(), &fdh->uv_handle, fdh->fd); - DBG("_ecore_main_fdh_poll_add3 %p", fdh->uv_handle.data); - _dl_uv_poll_start(&fdh->uv_handle, _ecore_main_uv_events_from_fdh(fdh) - , _ecore_main_uv_poll_cb); - DBG("_ecore_main_fdh_poll_add libuv DONE"); - } + if (!fdh->file) + { + DBG("_ecore_main_fdh_poll_add libuv socket %p", fdh); + fdh->uv_handle.data = fdh; + DBG("_ecore_main_fdh_poll_add2 %p", fdh); + _dl_uv_poll_init_socket(_dl_uv_default_loop(), + &fdh->uv_handle, fdh->fd); + DBG("_ecore_main_fdh_poll_add3 %p", fdh->uv_handle.data); + _dl_uv_poll_start(&fdh->uv_handle, + _ecore_main_uv_events_from_fdh(fdh) + , _ecore_main_uv_poll_cb); + DBG("_ecore_main_fdh_poll_add libuv DONE"); + } + else + { + DBG("_ecore_main_fdh_poll_add libuv file"); + fdh->uv_handle.data = fdh; + DBG("_ecore_main_fdh_poll_add2 %p", fdh); + _dl_uv_poll_init(_dl_uv_default_loop(), + &fdh->uv_handle, fdh->fd); + DBG("_ecore_main_fdh_poll_add3 %p", fdh->uv_handle.data); + _dl_uv_poll_start(&fdh->uv_handle, + _ecore_main_uv_events_from_fdh(fdh) + , _ecore_main_uv_poll_cb); + DBG("_ecore_main_fdh_poll_add libuv DONE"); + } #elif defined(USE_G_MAIN_LOOP) fdh->gfd.fd = fdh->fd; fdh->gfd.events = _gfd_events_from_fdh(fdh); @@ -540,47 +419,45 @@ _ecore_main_fdh_poll_add(Ecore_Fd_Handler *fdh) } static inline void -_ecore_main_fdh_poll_del(Ecore_Fd_Handler *fdh) +_ecore_main_fdh_poll_del(Efl_Loop_Data *pd, Ecore_Fd_Handler *fdh) { #ifdef HAVE_EPOLL -#ifdef HAVE_LIBUV - if(!_dl_uv_run) -#endif - { - if ((!fdh->file) && (epoll_fd >= 0)) - { - struct epoll_event ev; - int efd = _ecore_get_epoll_fd(); - - memset(&ev, 0, sizeof (ev)); - DBG("removing poll on %d", fdh->fd); - /* could get an EBADF if somebody closed the FD before removing it */ - if ((epoll_ctl(efd, EPOLL_CTL_DEL, fdh->fd, &ev) < 0)) - { - if (errno == EBADF) - { - WRN("fd %d was closed, can't remove from epoll - reinit!", - fdh->fd); - _ecore_main_loop_shutdown(); - _ecore_main_loop_init(); - } - else - { - ERR("Failed to delete epoll fd %d! (errno=%d)", fdh->fd, errno); - } - } - } +# ifdef HAVE_LIBUV + if (!_dl_uv_run) +# endif + { + if ((!fdh->file) && (pd->epoll_fd >= 0)) + { + struct epoll_event ev; + int efd = _ecore_get_epoll_fd(fdh->loop, pd); + + memset(&ev, 0, sizeof (ev)); + DBG("removing poll on %d", fdh->fd); + // could get an EBADF if somebody closed the FD before removing + if ((epoll_ctl(efd, EPOLL_CTL_DEL, fdh->fd, &ev) < 0)) + { + if (errno == EBADF) + { + WRN("fd %d closed, can't remove from epoll - reinit!", + fdh->fd); + _ecore_main_loop_clear(fdh->loop, pd); + _ecore_main_loop_setup(fdh->loop, pd); + } + else ERR("Failed to delete epoll fd %d! (errno=%d)", + fdh->fd, errno); + } + } } -#ifdef HAVE_LIBUV +# ifdef HAVE_LIBUV else -#endif +# endif #endif { #ifdef HAVE_LIBUV - DBG("_ecore_main_fdh_poll_del libuv %p", fdh); - uv_handle_t* h = (uv_handle_t*)&fdh->uv_handle; - _dl_uv_close(h, 0); - DBG("_ecore_main_fdh_poll_del libuv DONE"); + DBG("_ecore_main_fdh_poll_del libuv %p", fdh); + uv_handle_t* h = (uv_handle_t*)&fdh->uv_handle; + _dl_uv_close(h, 0); + DBG("_ecore_main_fdh_poll_del libuv DONE"); #elif USE_G_MAIN_LOOP fdh->gfd.fd = fdh->fd; fdh->gfd.events = _gfd_events_from_fdh(fdh); @@ -592,35 +469,35 @@ _ecore_main_fdh_poll_del(Ecore_Fd_Handler *fdh) } static inline int -_ecore_main_fdh_poll_modify(Ecore_Fd_Handler *fdh) +_ecore_main_fdh_poll_modify(Efl_Loop_Data *pd EINA_UNUSED, Ecore_Fd_Handler *fdh) { DBG("_ecore_main_fdh_poll_modify %p", fdh); int r = 0; #ifdef HAVE_EPOLL -#ifdef HAVE_LIBUV - if(!_dl_uv_run) -#endif +# ifdef HAVE_LIBUV + if (!_dl_uv_run) +# endif { - if ((!fdh->file) && (epoll_fd >= 0)) - { - struct epoll_event ev; - int efd = _ecore_get_epoll_fd(); - - memset(&ev, 0, sizeof (ev)); - ev.events = _ecore_poll_events_from_fdh(fdh); - ev.data.ptr = fdh; - DBG("modifing epoll on %d to %08x", fdh->fd, ev.events); - r = epoll_ctl(efd, EPOLL_CTL_MOD, fdh->fd, &ev); - } + if ((!fdh->file) && (pd->epoll_fd >= 0)) + { + struct epoll_event ev; + int efd = _ecore_get_epoll_fd(fdh->loop, pd); + + memset(&ev, 0, sizeof (ev)); + ev.events = _ecore_poll_events_from_fdh(fdh); + ev.data.ptr = fdh; + DBG("modifing epoll on %d to %08x", fdh->fd, ev.events); + r = epoll_ctl(efd, EPOLL_CTL_MOD, fdh->fd, &ev); + } } -#ifdef HAVE_LIBUV +# ifdef HAVE_LIBUV else -#endif +# endif #endif { #ifdef HAVE_LIBUV - _dl_uv_poll_start(&fdh->uv_handle, _ecore_main_uv_events_from_fdh(fdh) - , _ecore_main_uv_poll_cb); + _dl_uv_poll_start(&fdh->uv_handle, _ecore_main_uv_events_from_fdh(fdh) + , _ecore_main_uv_poll_cb); #elif defined(USE_G_MAIN_LOOP) fdh->gfd.fd = fdh->fd; fdh->gfd.events = _gfd_events_from_fdh(fdh); @@ -633,12 +510,12 @@ _ecore_main_fdh_poll_modify(Ecore_Fd_Handler *fdh) #ifdef HAVE_EPOLL static inline int -_ecore_main_fdh_epoll_mark_active(void) +_ecore_main_fdh_epoll_mark_active(Eo *obj, Efl_Loop_Data *pd) { DBG("_ecore_main_fdh_epoll_mark_active"); struct epoll_event ev[32]; int i, ret; - int efd = _ecore_get_epoll_fd(); + int efd = _ecore_get_epoll_fd(obj, pd); memset(&ev, 0, sizeof (ev)); ret = epoll_wait(efd, ev, sizeof(ev) / sizeof(struct epoll_event), 0); @@ -666,42 +543,33 @@ _ecore_main_fdh_epoll_mark_active(void) continue; } - if (ev[i].events & EPOLLIN) - fdh->read_active = EINA_TRUE; - if (ev[i].events & EPOLLOUT) - fdh->write_active = EINA_TRUE; - if (ev[i].events & EPOLLERR) - fdh->error_active = EINA_TRUE; + if (ev[i].events & EPOLLIN) fdh->read_active = EINA_TRUE; + if (ev[i].events & EPOLLOUT) fdh->write_active = EINA_TRUE; + if (ev[i].events & EPOLLERR) fdh->error_active = EINA_TRUE; - _ecore_try_add_to_call_list(fdh); + _ecore_try_add_to_call_list(obj, pd, fdh); } - return ret; } #endif #ifdef USE_G_MAIN_LOOP - static inline int -_ecore_main_fdh_glib_mark_active(void) +_ecore_main_fdh_glib_mark_active(Eo *obj, Efl_Loop_Data *pd) { Ecore_Fd_Handler *fdh; int ret = 0; /* call the prepare callback for all handlers */ - EINA_INLIST_FOREACH(fd_handlers, fdh) + EINA_INLIST_FOREACH(pd->fd_handlers, fdh) { - if (fdh->delete_me) - continue; + if (fdh->delete_me) continue; - if (fdh->gfd.revents & G_IO_IN) - fdh->read_active = EINA_TRUE; - if (fdh->gfd.revents & G_IO_OUT) - fdh->write_active = EINA_TRUE; - if (fdh->gfd.revents & G_IO_ERR) - fdh->error_active = EINA_TRUE; + if (fdh->gfd.revents & G_IO_IN) fdh->read_active = EINA_TRUE; + if (fdh->gfd.revents & G_IO_OUT) fdh->write_active = EINA_TRUE; + if (fdh->gfd.revents & G_IO_ERR) fdh->error_active = EINA_TRUE; - _ecore_try_add_to_call_list(fdh); + _ecore_try_add_to_call_list(obj, fdh); if (fdh->gfd.revents & (G_IO_IN | G_IO_OUT | G_IO_ERR)) ret++; } @@ -714,159 +582,164 @@ static gboolean _ecore_main_gsource_prepare(GSource *source EINA_UNUSED, gint *next_time) { + Eo *obj = ML_OBJ; + Efl_Loop_Data *pd = ML_DAT; gboolean ready = FALSE; in_main_loop++; + pd->in_loop = in_main_loop; - if (!ecore_idling && !_ecore_glib_idle_enterer_called) + if ((!ecore_idling) && (!_ecore_glib_idle_enterer_called)) { - _ecore_time_loop_time = ecore_time_get(); - _efl_loop_timer_expired_timers_call(_ecore_time_loop_time); + pd->loop_time = _ecore_time_loop_time = ecore_time_get(); + _efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time); - _ecore_idle_enterer_call(_mainloop_singleton); + _ecore_idle_enterer_call(obj); _ecore_throttle(); + _throttle_do(pd); _ecore_glib_idle_enterer_called = FALSE; - if (fd_handlers_with_buffer) - _ecore_main_fd_handlers_buf_call(); + if (pd->fd_handlers_with_buffer) + _ecore_main_fd_handlers_buf_call(obj, pd); } - _ecore_signal_received_process(); + _ecore_signal_received_process(obj, pd); - /* don't check fds if somebody quit */ + // don't check fds if somebody quit if (g_main_loop_is_running(ecore_main_loop)) { - /* only set idling state in dispatch */ - if (ecore_idling && !_ecore_idler_exist(_mainloop_singleton) && !_ecore_event_exist()) - { - if (_efl_loop_timers_exists()) - { - int r = -1; - double t = _efl_loop_timer_next_get(); - - if ((timer_fd >= 0) && (t > 0.0)) - { - struct itimerspec ts; - - ts.it_interval.tv_sec = 0; - ts.it_interval.tv_nsec = 0; - ts.it_value.tv_sec = t; - ts.it_value.tv_nsec = fmod(t * NS_PER_SEC, NS_PER_SEC); - - /* timerfd cannot sleep for 0 time */ - if (ts.it_value.tv_sec || ts.it_value.tv_nsec) - { - r = timerfd_settime(timer_fd, 0, &ts, NULL); - if (r < 0) - { - ERR("timer set returned %d (errno=%d)", r, errno); - close(timer_fd); - timer_fd = -1; - } - else - INF("sleeping for %ld s %06ldus", - ts.it_value.tv_sec, - ts.it_value.tv_nsec / 1000); - } - } - if (r == -1) - { - *next_time = ceil(t * 1000.0); - if (t == 0.0) - ready = TRUE; - } - } - else - *next_time = -1; - } - else - { - *next_time = 0; - if (_ecore_event_exist()) - ready = TRUE; - } - - if (fd_handlers_with_prep) - _ecore_main_prepare_handlers(); + // only set idling state in dispatch + if (ecore_idling && (!_ecore_idler_exist(obj)) && + (!efl_loop_message_exists(obj))) + { + if (_efl_loop_timers_exists(obj, pd)) + { + int r = -1; + double t = _efl_loop_timer_next_get(obj, pd); + + if ((timer_fd >= 0) && (t > 0.0)) + { + struct itimerspec ts; + + ts.it_interval.tv_sec = 0; + ts.it_interval.tv_nsec = 0; + ts.it_value.tv_sec = t; + ts.it_value.tv_nsec = fmod(t * NS_PER_SEC, NS_PER_SEC); + + // timerfd cannot sleep for 0 time + if (ts.it_value.tv_sec || ts.it_value.tv_nsec) + { + r = timerfd_settime(timer_fd, 0, &ts, NULL); + if (r < 0) + { + ERR("timer set returned %d (errno=%d)", + r, errno); + close(timer_fd); + timer_fd = -1; + } + else INF("sleeping for %ld s %06ldus", + ts.it_value.tv_sec, + ts.it_value.tv_nsec / 1000); + } + } + if (r == -1) + { + *next_time = ceil(t * 1000.0); + if (t == 0.0) ready = TRUE; + } + } + else *next_time = -1; + } + else + { + *next_time = 0; + if (efl_loop_message_exists(obj)) ready = TRUE; + } + + if (pd->fd_handlers_with_prep) _ecore_main_prepare_handlers(obj, pd); } - else - ready = TRUE; + else ready = TRUE; in_main_loop--; + pd->in_loop = in_main_loop; DBG("leave, timeout = %d", *next_time); - /* ready if we're not running (about to quit) */ + // ready if we're not running (about to quit) return ready; } static gboolean _ecore_main_gsource_check(GSource *source EINA_UNUSED) { + Eo *obj = ML_OBJ; + Efl_Loop_Data *pd = ML_DAT; gboolean ret = FALSE; in_main_loop++; - - /* check if old timers expired */ - if (ecore_idling && !_ecore_idler_exist(_mainloop_singleton) && !_ecore_event_exist()) + pd->in_loop = in_main_loop; + // check if old timers expired + if (ecore_idling && (!_ecore_idler_exist(obj)) && + (!efl_loop_message_exists(obj))) { if (timer_fd >= 0) { uint64_t count = 0; int r = read(timer_fd, &count, sizeof count); if ((r == -1) && (errno == EAGAIN)) - ; - else if (r == sizeof count) - ret = TRUE; + { + } + else if (r == sizeof count) ret = TRUE; else { - /* unexpected things happened... fail back to old way */ - ERR("timer read returned %d (errno=%d)", r, errno); - close(timer_fd); - timer_fd = -1; + // unexpected things happened... fail back to old way + ERR("timer read returned %d (errno=%d)", r, errno); + close(timer_fd); + timer_fd = -1; } } } - else - ret = TRUE; + else ret = TRUE; - /* check if fds are ready */ + // check if fds are ready #ifdef HAVE_EPOLL - if (epoll_fd >= 0) - ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active() > 0); + if (pd->epoll_fd >= 0) + ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active(obj, pd) > 0); else #endif - ecore_fds_ready = (_ecore_main_fdh_glib_mark_active() > 0); - _ecore_main_fd_handlers_cleanup(); - if (ecore_fds_ready) - ret = TRUE; + ecore_fds_ready = (_ecore_main_fdh_glib_mark_active(obj, pd) > 0); + _ecore_main_fd_handlers_cleanup(obj, pd); + if (ecore_fds_ready) ret = TRUE; - /* check timers after updating loop time */ - if (!ret && _efl_loop_timers_exists()) - ret = (0.0 == _efl_loop_timer_next_get()); + // check timers after updating loop time + if (!ret && _efl_loop_timers_exists(obj, pd)) + ret = (0.0 == _efl_loop_timer_next_get(obj, pd)); in_main_loop--; - + pd->in_loop = in_main_loop; return ret; } -/* like we just came out of main_loop_select in _ecore_main_select */ +// like we just came out of main_loop_select in _ecore_main_select static gboolean _ecore_main_gsource_dispatch(GSource *source EINA_UNUSED, GSourceFunc callback EINA_UNUSED, gpointer user_data EINA_UNUSED) { + Eo *obj = ML_OBJ; + Efl_Loop_Data *pd = ML_DAT; gboolean events_ready, timers_ready, idlers_ready; double next_time; - _ecore_time_loop_time = ecore_time_get(); - _efl_loop_timer_enable_new(); - next_time = _efl_loop_timer_next_get(); + pd->loop_time = ecore_time_get(); + _efl_loop_timer_enable_new(obj, pd); + next_time = _efl_loop_timer_next_get(obj, pd); - events_ready = _ecore_event_exist(); - timers_ready = _efl_loop_timers_exists() && (0.0 == next_time); - idlers_ready = _ecore_idler_exist(_mainloop_singleton); + events_ready = efl_loop_message_exists(obj); + timers_ready = _efl_loop_timers_exists(obj, pd) && (0.0 == next_time); + idlers_ready = _ecore_idler_exist(obj); in_main_loop++; + pd->in_loop = in_main_loop; DBG("enter idling=%d fds=%d events=%d timers=%d (next=%.2f) idlers=%d", ecore_idling, ecore_fds_ready, events_ready, timers_ready, next_time, idlers_ready); @@ -874,51 +747,50 @@ _ecore_main_gsource_dispatch(GSource *source EINA_UNUSED, if (ecore_idling && events_ready) { _ecore_animator_run_reset(); - _ecore_idle_exiter_call(_mainloop_singleton); + _ecore_idle_exiter_call(obj); ecore_idling = 0; } - else if (!ecore_idling && !events_ready) - { - ecore_idling = 1; - } + else if (!ecore_idling && !events_ready) ecore_idling = 1; if (ecore_idling) { - _ecore_idler_all_call(_mainloop_singleton); + _ecore_idler_all_call(obj); - events_ready = _ecore_event_exist(); + events_ready = efl_loop_message_exists(obj); if (ecore_fds_ready || events_ready || timers_ready) { _ecore_animator_run_reset(); - _ecore_idle_exiter_call(_mainloop_singleton); + _ecore_idle_exiter_call(obj); ecore_idling = 0; } } - /* process events */ + // process events if (!ecore_idling) { - _ecore_main_fd_handlers_call(); - if (fd_handlers_with_buffer) - _ecore_main_fd_handlers_buf_call(); - _ecore_signal_received_process(); - _ecore_event_call(); - _ecore_main_fd_handlers_cleanup(); + _ecore_main_fd_handlers_call(obj, pd); + if (pd->fd_handlers_with_buffer) + _ecore_main_fd_handlers_buf_call(obj, pd); + _ecore_signal_received_process(obj, pd); + efl_loop_message_process(obj); + _ecore_main_fd_handlers_cleanup(obj, pd); - _efl_loop_timer_expired_timers_call(_ecore_time_loop_time); + _efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time); - _ecore_idle_enterer_call(_mainloop_singleton); + _ecore_idle_enterer_call(obj); _ecore_throttle(); + _throttle_do(pd); _ecore_glib_idle_enterer_called = TRUE; - if (fd_handlers_with_buffer) - _ecore_main_fd_handlers_buf_call(); + if (pd->fd_handlers_with_buffer) + _ecore_main_fd_handlers_buf_call(obj, pd); } in_main_loop--; + pd->in_loop = in_main_loop; - return TRUE; /* what should be returned here? */ + return TRUE; // what should be returned here? } static void @@ -928,432 +800,438 @@ _ecore_main_gsource_finalize(GSource *source EINA_UNUSED) static GSourceFuncs ecore_gsource_funcs = { - .prepare = _ecore_main_gsource_prepare, - .check = _ecore_main_gsource_check, + .prepare = _ecore_main_gsource_prepare, + .check = _ecore_main_gsource_check, .dispatch = _ecore_main_gsource_dispatch, .finalize = _ecore_main_gsource_finalize, }; - #endif -#ifdef HAVE_SYS_TIMERFD_H -static int realtime_fd = -1; - -static void detect_time_changes_start(void); -static Eina_Bool -_realtime_update(void *data EINA_UNUSED, Ecore_Fd_Handler *fdh EINA_UNUSED) -{ - char buf[64]; - - if (read(realtime_fd, buf, sizeof(buf)) >= 0) return EINA_TRUE; - - DBG("system clock changed"); - ecore_event_add(ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED, NULL, NULL, NULL); - - close(realtime_fd); - realtime_fd = -1; - detect_time_changes_start(); - return EINA_FALSE; -} -#endif +#ifdef HAVE_LIBUV +static inline void _ecore_main_loop_uv_check(uv_check_t *handle); +static void _ecore_main_loop_uv_prepare(uv_prepare_t *handle); static void -detect_time_changes_start(void) +_ecore_main_loop_timer_run(uv_timer_t *timer EINA_UNUSED) { -#ifdef HAVE_SYS_TIMERFD_H - struct itimerspec its; - - if (realtime_fd >= 0) return; + Eo *obj = ML_OBJ; + Efl_Loop_Data *pd = ML_DAT; - realtime_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC); - if (realtime_fd < 0) return; - - memset(&its, 0, sizeof(its)); - its.it_value.tv_sec = 0x7ffffff0; // end of time - 0xf - if (timerfd_settime(realtime_fd, - TFD_TIMER_ABSTIME | TFD_TIMER_CANCELON_SET, - &its, NULL) < 0) + if (_ecore_main_uv_idling) { - WRN("Couldn't arm timerfd to detect clock changes: %s", - strerror(errno)); - close(realtime_fd); - realtime_fd = -1; - return; + _ecore_main_uv_idling = EINA_FALSE; + _ecore_idle_exiter_call(obj); + _ecore_animator_run_reset(); } - - ecore_main_fd_handler_add(realtime_fd, ECORE_FD_READ, - _realtime_update, NULL, NULL, NULL); -#endif + pd->loop_time = ecore_time_get(); + _ecore_main_loop_uv_check(NULL); + _ecore_main_loop_uv_prepare(NULL); } -static void -detect_time_changes_stop(void) +static inline void +_ecore_main_loop_uv_check(uv_check_t *handle EINA_UNUSED) { -#ifdef HAVE_SYS_TIMERFD_H - if (realtime_fd > 0) - { - close(realtime_fd); - realtime_fd = -1; - } -#endif -} + Eo *obj = ML_OBJ; + Efl_Loop_Data *pd = ML_DAT; - -#ifdef HAVE_LIBUV -static inline -void -_ecore_main_loop_uv_check(uv_check_t* handle EINA_UNUSED); -static void _ecore_main_loop_uv_prepare(uv_prepare_t* handle); - -static -void _ecore_main_loop_timer_run(uv_timer_t* timer EINA_UNUSED) -{ - if(_ecore_main_uv_idling) - { - _ecore_main_uv_idling = EINA_FALSE; - _ecore_idle_exiter_call(_mainloop_singleton); - _ecore_animator_run_reset(); - } - _ecore_time_loop_time = ecore_time_get(); - _ecore_main_loop_uv_check(NULL); - - _ecore_main_loop_uv_prepare(NULL); -} -static void _ecore_main_loop_uv_prepare(uv_prepare_t* handle); - -static inline -void -_ecore_main_loop_uv_check(uv_check_t* handle EINA_UNUSED) -{ DBG("_ecore_main_loop_uv_check idling? %d", (int)_ecore_main_uv_idling); in_main_loop++; + pd->in_loop = in_main_loop; - if(do_quit) - goto quit; + if (pd->do_quit) goto quit; do { - _ecore_main_fd_handlers_call(); - if (fd_handlers_with_buffer) - _ecore_main_fd_handlers_buf_call(); - _ecore_signal_received_process(); - _ecore_event_call(); - _ecore_main_fd_handlers_cleanup(); - _efl_loop_timer_expired_timers_call(_ecore_time_loop_time); + _ecore_main_fd_handlers_call(obj, pd); + if (pd->fd_handlers_with_buffer) + _ecore_main_fd_handlers_buf_call(obj, pd); + _ecore_signal_received_process(obj, pd); + efl_loop_message_process(obj); + _ecore_main_fd_handlers_cleanup(obj, pd); + _efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time); } - while(fd_handlers_to_call); + while (pd->fd_handlers_to_call); quit: in_main_loop--; + pd->in_loop = in_main_loop; } #endif -void -_ecore_main_loop_init(void) +static void +_ecore_main_loop_setup(Eo *obj, Efl_Loop_Data *pd) { - // Please note that this function is being also called in case of a bad fd to reset the main loop. - - DBG("_ecore_main_loop_init"); + // Please note that this function is being also called in case of a bad + // fd to reset the main loop. #ifdef HAVE_EPOLL - epoll_fd = epoll_create(1); - if (epoll_fd < 0) - WRN("Failed to create epoll fd!"); + pd->epoll_fd = epoll_create(1); + if (pd->epoll_fd < 0) WRN("Failed to create epoll fd!"); else { - eina_file_close_on_exec(epoll_fd, EINA_TRUE); + eina_file_close_on_exec(pd->epoll_fd, EINA_TRUE); - epoll_pid = getpid(); + pd->epoll_pid = getpid(); /* add polls on all our file descriptors */ Ecore_Fd_Handler *fdh; - EINA_INLIST_FOREACH(fd_handlers, fdh) + EINA_INLIST_FOREACH(pd->fd_handlers, fdh) { if (fdh->delete_me) continue; - _ecore_epoll_add(epoll_fd, fdh->fd, + _ecore_epoll_add(pd->epoll_fd, fdh->fd, _ecore_poll_events_from_fdh(fdh), fdh); - _ecore_main_fdh_poll_add(fdh); + _ecore_main_fdh_poll_add(pd, fdh); } } #endif -#ifdef HAVE_LIBUV - { - DBG("loading lib uv"); -#ifdef HAVE_NODEJS - void* lib = dlopen(NULL, RTLD_LAZY); -#else - void* lib = dlopen("libuv.so", RTLD_GLOBAL | RTLD_LAZY); -#endif - - if(lib && dlsym(lib, "uv_run")) - { - DBG("loaded lib uv"); - _dl_uv_run = dlsym(lib, "uv_run"); - assert(!!_dl_uv_run); - _dl_uv_stop = dlsym(lib, "uv_stop"); - assert(!!_dl_uv_stop); - _dl_uv_default_loop = dlsym(lib, "uv_default_loop"); - assert(!!_dl_uv_default_loop); - _dl_uv_poll_init_socket = dlsym(lib, "uv_poll_init_socket"); - assert(!!_dl_uv_poll_init_socket); - _dl_uv_poll_init = dlsym(lib, "uv_poll_init"); - assert(!!_dl_uv_poll_init); - _dl_uv_poll_start = dlsym(lib, "uv_poll_start"); - assert(!!_dl_uv_poll_start); - _dl_uv_poll_stop = dlsym(lib, "uv_poll_stop"); - assert(!!_dl_uv_poll_stop); - _dl_uv_timer_init = dlsym(lib, "uv_timer_init"); - assert(!!_dl_uv_timer_init); - _dl_uv_timer_start = dlsym(lib, "uv_timer_start"); - assert(!!_dl_uv_timer_start); - _dl_uv_timer_stop = dlsym(lib, "uv_timer_stop"); - assert(!!_dl_uv_timer_stop); - _dl_uv_prepare_init = dlsym(lib, "uv_prepare_init"); - assert(!!_dl_uv_prepare_init); - _dl_uv_prepare_start = dlsym(lib, "uv_prepare_start"); - assert(!!_dl_uv_prepare_start); - _dl_uv_prepare_stop = dlsym(lib, "uv_prepare_stop"); - assert(!!_dl_uv_prepare_stop); - _dl_uv_check_init = dlsym(lib, "uv_check_init"); - assert(!!_dl_uv_check_init); - _dl_uv_check_start = dlsym(lib, "uv_check_start"); - assert(!!_dl_uv_check_start); - _dl_uv_check_stop = dlsym(lib, "uv_check_stop"); - assert(!!_dl_uv_check_stop); - _dl_uv_close = dlsym(lib, "uv_close"); - assert(!!_dl_uv_close); - _dl_uv_loop_alive = dlsym(lib, "uv_loop_alive"); - assert(!!_dl_uv_loop_alive); - - //dlclose(lib); - - DBG("_dl_uv_prepare_init"); - _dl_uv_prepare_init(_dl_uv_default_loop(), &_ecore_main_uv_prepare); - DBG("_dl_uv_prepare_start"); - _dl_uv_prepare_start(&_ecore_main_uv_prepare, &_ecore_main_loop_uv_prepare); - DBG("_dl_uv_prepare_started"); - - DBG("_dl_uv_check_init"); - _dl_uv_check_init(_dl_uv_default_loop(), &_ecore_main_uv_check); - DBG("_dl_uv_check_start"); - _dl_uv_check_start(&_ecore_main_uv_check, &_ecore_main_loop_uv_check); - DBG("_dl_uv_check_started"); - - _dl_uv_timer_init(_dl_uv_default_loop(), &_ecore_main_uv_handle_timers); - } - /* else */ - /* DBG("did not load uv"); */ - DBG("loaded dlsyms uv"); - } -#endif - - /* setup for the g_main_loop only integration */ -#ifdef USE_G_MAIN_LOOP - ecore_glib_source = g_source_new(&ecore_gsource_funcs, sizeof (GSource)); - if (!ecore_glib_source) - CRI("Failed to create glib source for epoll!"); - else + if (obj == ML_OBJ) { - g_source_set_priority(ecore_glib_source, G_PRIORITY_HIGH_IDLE + 20); -#ifdef HAVE_EPOLL - if (epoll_fd >= 0) +#ifdef HAVE_LIBUV + // XXX: FIXME: the below uv init should not assert but gracefully + // fail with errors + DBG("loading lib uv"); +# ifdef HAVE_NODEJS + void *lib = dlopen(NULL, RTLD_LAZY); +# else + void *lib = dlopen("libuv.so.1", RTLD_GLOBAL | RTLD_LAZY); +# endif + + if (lib && dlsym(lib, "uv_run")) { - /* epoll multiplexes fds into the g_main_loop */ - ecore_epoll_fd.fd = epoll_fd; - ecore_epoll_fd.events = G_IO_IN; - ecore_epoll_fd.revents = 0; - g_source_add_poll(ecore_glib_source, &ecore_epoll_fd); + DBG("loaded lib uv"); + _dl_uv_run = dlsym(lib, "uv_run"); + assert(!!_dl_uv_run); + _dl_uv_stop = dlsym(lib, "uv_stop"); + assert(!!_dl_uv_stop); + _dl_uv_default_loop = dlsym(lib, "uv_default_loop"); + assert(!!_dl_uv_default_loop); + _dl_uv_poll_init_socket = dlsym(lib, "uv_poll_init_socket"); + assert(!!_dl_uv_poll_init_socket); + _dl_uv_poll_init = dlsym(lib, "uv_poll_init"); + assert(!!_dl_uv_poll_init); + _dl_uv_poll_start = dlsym(lib, "uv_poll_start"); + assert(!!_dl_uv_poll_start); + _dl_uv_poll_stop = dlsym(lib, "uv_poll_stop"); + assert(!!_dl_uv_poll_stop); + _dl_uv_timer_init = dlsym(lib, "uv_timer_init"); + assert(!!_dl_uv_timer_init); + _dl_uv_timer_start = dlsym(lib, "uv_timer_start"); + assert(!!_dl_uv_timer_start); + _dl_uv_timer_stop = dlsym(lib, "uv_timer_stop"); + assert(!!_dl_uv_timer_stop); + _dl_uv_prepare_init = dlsym(lib, "uv_prepare_init"); + assert(!!_dl_uv_prepare_init); + _dl_uv_prepare_start = dlsym(lib, "uv_prepare_start"); + assert(!!_dl_uv_prepare_start); + _dl_uv_prepare_stop = dlsym(lib, "uv_prepare_stop"); + assert(!!_dl_uv_prepare_stop); + _dl_uv_check_init = dlsym(lib, "uv_check_init"); + assert(!!_dl_uv_check_init); + _dl_uv_check_start = dlsym(lib, "uv_check_start"); + assert(!!_dl_uv_check_start); + _dl_uv_check_stop = dlsym(lib, "uv_check_stop"); + assert(!!_dl_uv_check_stop); + _dl_uv_close = dlsym(lib, "uv_close"); + assert(!!_dl_uv_close); + _dl_uv_loop_alive = dlsym(lib, "uv_loop_alive"); + assert(!!_dl_uv_loop_alive); + + //dlclose(lib); + + DBG("_dl_uv_prepare_init"); + _dl_uv_prepare_init(_dl_uv_default_loop(), &_ecore_main_uv_prepare); + DBG("_dl_uv_prepare_start"); + _dl_uv_prepare_start(&_ecore_main_uv_prepare, &_ecore_main_loop_uv_prepare); + DBG("_dl_uv_prepare_started"); + + DBG("_dl_uv_check_init"); + _dl_uv_check_init(_dl_uv_default_loop(), &_ecore_main_uv_check); + DBG("_dl_uv_check_start"); + _dl_uv_check_start(&_ecore_main_uv_check, &_ecore_main_loop_uv_check); + DBG("_dl_uv_check_started"); + + _dl_uv_timer_init(_dl_uv_default_loop(), &_ecore_main_uv_handle_timers); } + // else + // DBG("did not load uv"); + DBG("loaded dlsyms uv"); #endif - /* timerfd gives us better than millisecond accuracy in g_main_loop */ - timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); - if (timer_fd < 0) - WRN("failed to create timer fd!"); + + // setup for the g_main_loop only integration +#ifdef USE_G_MAIN_LOOP + ecore_glib_source = g_source_new(&ecore_gsource_funcs, + sizeof(GSource)); + if (!ecore_glib_source) CRI("Failed to create glib source for epoll!"); else { - eina_file_close_on_exec(timer_fd, EINA_TRUE); - ecore_timer_fd.fd = timer_fd; - ecore_timer_fd.events = G_IO_IN; - ecore_timer_fd.revents = 0; - g_source_add_poll(ecore_glib_source, &ecore_timer_fd); - } + g_source_set_priority(ecore_glib_source, + G_PRIORITY_HIGH_IDLE + 20); +# ifdef HAVE_EPOLL + if (pd->epoll_fd >= 0) + { + // epoll multiplexes fds into the g_main_loop + ecore_epoll_fd.fd = pd->epoll_fd; + ecore_epoll_fd.events = G_IO_IN; + ecore_epoll_fd.revents = 0; + g_source_add_poll(ecore_glib_source, &ecore_epoll_fd); + } +# endif + // timerfd gives us better than millisecond accuracy + pd->timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); + if (pd->timer_fd < 0) WRN("failed to create timer fd!"); + else + { + eina_file_close_on_exec(pd->timer_fd, EINA_TRUE); + ecore_timer_fd.fd = pd->timer_fd; + ecore_timer_fd.events = G_IO_IN; + ecore_timer_fd.revents = 0; + g_source_add_poll(ecore_glib_source, &ecore_timer_fd); + } - ecore_glib_source_id = g_source_attach(ecore_glib_source, NULL); - if (ecore_glib_source_id <= 0) - CRI("Failed to attach glib source to default context"); - } + ecore_glib_source_id = g_source_attach(ecore_glib_source, NULL); + if (ecore_glib_source_id <= 0) + CRI("Failed to attach glib source to default context"); + } #endif - - detect_time_changes_start(); + } + _ecore_main_timechanges_start(obj); } -void -_ecore_main_loop_shutdown(void) +static void +_ecore_main_loop_clear(Eo *obj, Efl_Loop_Data *pd) { - // Please note that _ecore_main_loop_shutdown is called in cycle to restart the main loop in case of a bad fd - -#ifdef USE_G_MAIN_LOOP - if (ecore_glib_source) + if (!pd) return; + // Please note that _ecore_main_loop_shutdown is called in cycle to + // restart the main loop in case of a bad fd + if (obj == ML_OBJ) { - g_source_destroy(ecore_glib_source); - ecore_glib_source = NULL; - } + _ecore_main_timechanges_stop(obj); +#ifdef USE_G_MAIN_LOOP + if (ecore_glib_source) + { + g_source_destroy(ecore_glib_source); + ecore_glib_source = NULL; + } #endif - - detect_time_changes_stop(); - -#ifdef HAVE_EPOLL - if (epoll_fd >= 0) - { - close(epoll_fd); - epoll_fd = -1; - } - epoll_pid = 0; +#ifdef HAVE_LIBUV + if (_dl_uv_run) + { + DBG("_ecore_main_loop_shutdown"); + _dl_uv_timer_stop(&_ecore_main_uv_handle_timers); + _dl_uv_close((uv_handle_t*)&_ecore_main_uv_handle_timers, 0); + } #endif - - if (timer_fd >= 0) + } +#ifdef HAVE_EPOLL + if (pd->epoll_fd >= 0) { - close(timer_fd); - timer_fd = -1; + close(pd->epoll_fd); + pd->epoll_fd = -1; } - -#ifdef HAVE_LIBUV - if(_dl_uv_run) + if (pd->timer_fd >= 0) { - DBG("_ecore_main_loop_shutdown"); - _dl_uv_timer_stop(&_ecore_main_uv_handle_timers); - _dl_uv_close((uv_handle_t*)&_ecore_main_uv_handle_timers, 0); + close(pd->timer_fd); + pd->timer_fd = -1; } #endif } -void * -_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) +void +_ecore_main_loop_init(void) { - DBG("_ecore_main_fd_handler_del %p", fd_handler); - if (fd_handler->delete_me) - { - ERR("fdh %p deleted twice", fd_handler); - return NULL; - } + DBG("_ecore_main_loop_init"); + if (!ecore_main_loop_get()) ERR("Cannot create main loop object"); + _ecore_main_loop_setup(ML_OBJ, ML_DAT); +} - fd_handler->delete_me = EINA_TRUE; - _ecore_main_fdh_poll_del(fd_handler); - fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fd_handler); - if (fd_handler->prep_func && fd_handlers_with_prep) - fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fd_handler); - if (fd_handler->buf_func && fd_handlers_with_buffer) - fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fd_handler); - return fd_handler->data; +void +_ecore_main_loop_shutdown(void) +{ + if (!ML_OBJ) return; + _ecore_main_loop_clear(ML_OBJ, ML_DAT); +// XXX: this seemingly closes fd's it shouldn't.... :( fd 0? +// efl_del(ML_OBJ); + ML_OBJ = NULL; + ML_DAT = NULL; } -EAPI void -ecore_main_loop_iterate(void) +void +_ecore_main_loop_iterate(Eo *obj, Efl_Loop_Data *pd) { - EINA_MAIN_LOOP_CHECK_RETURN; + if (obj == ML_OBJ) + { #ifdef HAVE_LIBUV - if(!_dl_uv_run) { + if (!_dl_uv_run) + { #endif #ifndef USE_G_MAIN_LOOP - _ecore_time_loop_time = ecore_time_get(); - _ecore_main_loop_iterate_internal(1); + pd->loop_time = ecore_time_get(); + _ecore_main_loop_iterate_internal(obj, pd, 1); #else - g_main_context_iteration(NULL, 0); + g_main_context_iteration(NULL, 0); #endif #ifdef HAVE_LIBUV - } - else - _dl_uv_run(_dl_uv_default_loop(), UV_RUN_ONCE | UV_RUN_NOWAIT); + } + else + _dl_uv_run(_dl_uv_default_loop(), UV_RUN_ONCE | UV_RUN_NOWAIT); #endif + } + else + { + pd->loop_time = ecore_time_get(); + _ecore_main_loop_iterate_internal(obj, pd, 1); + } } -EAPI int -ecore_main_loop_iterate_may_block(int may_block) +int +_ecore_main_loop_iterate_may_block(Eo *obj, Efl_Loop_Data *pd, int may_block) { - EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + if (obj == ML_OBJ) + { #ifdef HAVE_LIBUV - if(!_dl_uv_run) { + if (!_dl_uv_run) + { #endif #ifndef USE_G_MAIN_LOOP - _ecore_time_loop_time = ecore_time_get(); -in_main_loop++; - _ecore_main_loop_iterate_internal(!may_block); -in_main_loop--; - return _ecore_event_exist(); + in_main_loop++; + pd->in_loop = in_main_loop; + pd->loop_time = ecore_time_get(); + _ecore_main_loop_iterate_internal(obj, pd, !may_block); + in_main_loop--; + pd->in_loop = in_main_loop; + return efl_loop_message_exists(obj); #else - return g_main_context_iteration(NULL, may_block); + return g_main_context_iteration(NULL, may_block); #endif #ifdef HAVE_LIBUV - } - else - _dl_uv_run(_dl_uv_default_loop(), may_block ? UV_RUN_ONCE | UV_RUN_NOWAIT : UV_RUN_ONCE); + } + else + _dl_uv_run(_dl_uv_default_loop(), + may_block ? (UV_RUN_ONCE | UV_RUN_NOWAIT) : UV_RUN_ONCE); #endif + } + else + { + pd->in_loop++; + pd->loop_time = ecore_time_get(); + _ecore_main_loop_iterate_internal(obj, pd, !may_block); + pd->in_loop--; + return efl_loop_message_exists(obj); + } return 0; } -EAPI void -ecore_main_loop_begin(void) +void +_ecore_main_loop_begin(Eo *obj, Efl_Loop_Data *pd) { - DBG("ecore_main_loop_begin"); - EINA_MAIN_LOOP_CHECK_RETURN; - if (in_main_loop > 0) + if (obj == ML_OBJ) { - ERR("Running ecore_main_loop_begin() inside an existing main loop"); - return; - } - eina_evlog("+mainloop", NULL, 0.0, NULL); + if (pd->in_loop > 0) + { + ERR("Beginning main loop() inside an existing main loop"); + return; + } #ifdef HAVE_SYSTEMD - sd_notify(0, "READY=1"); + sd_notify(0, "READY=1"); #endif #ifdef HAVE_LIBUV - if(!_dl_uv_run) { + if (!_dl_uv_run) + { #endif #ifndef USE_G_MAIN_LOOP - in_main_loop++; - _ecore_time_loop_time = ecore_time_get(); - while (do_quit == 0) _ecore_main_loop_iterate_internal(0); - do_quit = 0; - in_main_loop--; + in_main_loop++; + pd->in_loop = in_main_loop; + pd->loop_time = ecore_time_get(); + while (!pd->do_quit) + _ecore_main_loop_iterate_internal(obj, pd, 0); + pd->do_quit = 0; + in_main_loop--; + pd->in_loop = in_main_loop; #else - if (!do_quit) - { - if (!ecore_main_loop) - ecore_main_loop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(ecore_main_loop); - } - do_quit = 0; + if (!pd->do_quit) + { + if (!ecore_main_loop) + ecore_main_loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(ecore_main_loop); + } + pd->do_quit = 0; #endif #ifdef HAVE_LIBUV - } + } + else + { + DBG("uv_run"); + in_main_loop++; + pd->in_loop = in_main_loop; + pd->loop_time = ecore_time_get(); + while (!pd->do_quit) + _dl_uv_run(_dl_uv_default_loop(), UV_RUN_DEFAULT); + in_main_loop--; + pd->in_loop = in_main_loop; + pd->do_quit = 0; + DBG("quit"); + } +#endif + } else { - DBG("uv_run"); - _ecore_time_loop_time = ecore_time_get(); - in_main_loop++; - while(!do_quit) - _dl_uv_run(_dl_uv_default_loop(), UV_RUN_DEFAULT); - in_main_loop--; - do_quit = 0; - DBG("quit"); + pd->in_loop++; + pd->loop_time = ecore_time_get(); + while (!pd->do_quit) + _ecore_main_loop_iterate_internal(obj, pd, 0); + pd->do_quit = 0; + pd->in_loop--; } +} + +void +_ecore_main_loop_quit(Eo *obj, Efl_Loop_Data *pd) +{ + pd->do_quit = 1; + if (obj != ML_OBJ) return; +#ifdef USE_G_MAIN_LOOP + if (ecore_main_loop) g_main_loop_quit(ecore_main_loop); +#elif defined(HAVE_LIBUV) + if (_dl_uv_run) _dl_uv_stop(_dl_uv_default_loop()); #endif +} + +EAPI void +ecore_main_loop_iterate(void) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + efl_loop_iterate(ML_OBJ); +} + +EAPI int +ecore_main_loop_iterate_may_block(int may_block) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); + return efl_loop_iterate_may_block(ML_OBJ, may_block); +} + +EAPI void +ecore_main_loop_begin(void) +{ + DBG("ecore_main_loop_begin"); + EINA_MAIN_LOOP_CHECK_RETURN; + eina_evlog("+mainloop", NULL, 0.0, NULL); + efl_loop_begin(ML_OBJ); eina_evlog("-mainloop", NULL, 0.0, NULL); } EAPI void ecore_main_loop_quit(void) { + Eina_Value v = EINA_VALUE_EMPTY; + int val = 0; + + eina_value_setup(&v, EINA_VALUE_TYPE_INT); + eina_value_set(&v, &val); EINA_MAIN_LOOP_CHECK_RETURN; - do_quit = 1; -#ifdef USE_G_MAIN_LOOP - if (ecore_main_loop) - g_main_loop_quit(ecore_main_loop); -#elif defined(HAVE_LIBUV) - if (_dl_uv_run) - _dl_uv_stop(_dl_uv_default_loop()); -#endif + efl_loop_quit(ML_OBJ, v); } -EAPI int +EAPI int ecore_main_loop_nested_get(void) { return in_main_loop; @@ -1381,7 +1259,10 @@ ecore_main_loop_select_func_get(void) } Ecore_Fd_Handler * -_ecore_main_fd_handler_add(int fd, +_ecore_main_fd_handler_add(Eo *obj, + Efl_Loop_Data *pd, + Eo *handler, + int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data, @@ -1397,36 +1278,63 @@ _ecore_main_fd_handler_add(int fd, fdh = ecore_fd_handler_calloc(1); if (!fdh) return NULL; ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER); - fdh->next_ready = NULL; + fdh->loop = obj; + fdh->loop_data = pd; + fdh->handler = handler; fdh->fd = fd; fdh->flags = flags; fdh->file = is_file; - if (_ecore_main_fdh_poll_add(fdh) < 0) + if (_ecore_main_fdh_poll_add(pd, fdh) < 0) { int err = errno; - ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err)); + ERR("Failed to add poll on fd %d (errno = %d: %s)!", + fd, err, strerror(err)); ecore_fd_handler_mp_free(fdh); return NULL; } - fdh->read_active = EINA_FALSE; - fdh->write_active = EINA_FALSE; - fdh->error_active = EINA_FALSE; - fdh->delete_me = EINA_FALSE; fdh->func = func; fdh->data = (void *)data; fdh->buf_func = buf_func; if (buf_func) - fd_handlers_with_buffer = eina_list_append(fd_handlers_with_buffer, fdh); + pd->fd_handlers_with_buffer = eina_list_append + (pd->fd_handlers_with_buffer, fdh); fdh->buf_data = (void *)buf_data; if (is_file) - file_fd_handlers = eina_list_append(file_fd_handlers, fdh); - fd_handlers = (Ecore_Fd_Handler *) - eina_inlist_append(EINA_INLIST_GET(fd_handlers), + pd->file_fd_handlers = eina_list_append + (pd->file_fd_handlers, fdh); + pd->fd_handlers = (Ecore_Fd_Handler *) + eina_inlist_append(EINA_INLIST_GET(pd->fd_handlers), EINA_INLIST_GET(fdh)); return fdh; } +void * +_ecore_main_fd_handler_del(Eo *obj EINA_UNUSED, + Efl_Loop_Data *pd, + Ecore_Fd_Handler *fd_handler) +{ + DBG("_ecore_main_fd_handler_del %p", fd_handler); + if (fd_handler->delete_me) + { + ERR("fdh %p deleted twice", fd_handler); + return NULL; + } + + fd_handler->handler = NULL; + fd_handler->delete_me = EINA_TRUE; + _ecore_main_fdh_poll_del(pd, fd_handler); + pd->fd_handlers_to_delete = eina_list_append + (pd->fd_handlers_to_delete, fd_handler); + if (fd_handler->prep_func && pd->fd_handlers_with_prep) + pd->fd_handlers_with_prep = eina_list_remove + (pd->fd_handlers_with_prep, fd_handler); + if (fd_handler->buf_func && pd->fd_handlers_with_buffer) + pd->fd_handlers_with_buffer = eina_list_remove + (pd->fd_handlers_with_buffer, fd_handler); + return fd_handler->data; +} + EAPI Ecore_Fd_Handler * ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, @@ -1437,7 +1345,9 @@ ecore_main_fd_handler_add(int fd, { Ecore_Fd_Handler *fdh = NULL; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - fdh = _ecore_main_fd_handler_add(fd, flags, func, data, buf_func, buf_data, EINA_FALSE); + fdh = _ecore_main_fd_handler_add(efl_loop_main_get(EFL_LOOP_CLASS), + ML_DAT, NULL, fd, flags, func, data, + buf_func, buf_data, EINA_FALSE); return fdh; } @@ -1450,15 +1360,36 @@ ecore_main_fd_handler_file_add(int fd, const void *buf_data) { EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - return _ecore_main_fd_handler_add(fd, flags, func, data, buf_func, buf_data, EINA_TRUE); + return _ecore_main_fd_handler_add(efl_loop_main_get(EFL_LOOP_CLASS), + ML_DAT, NULL, fd, flags, func, data, + buf_func, buf_data, EINA_TRUE); +} + +EAPI void * +ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) +{ + if (!fd_handler) return NULL; + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + + if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) + { + ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, + "ecore_main_fd_handler_del"); + return NULL; + } + return _ecore_main_fd_handler_del(ML_OBJ, ML_DAT, fd_handler); } #ifdef _WIN32 EAPI Ecore_Win32_Handler * -ecore_main_win32_handler_add(void *h, - Ecore_Win32_Handle_Cb func, - const void *data) -{ +_ecore_main_win32_handler_add(Eo *obj, + Efl_Loop_Data *pd, + Eo *handler, + void *h, + Ecore_Win32_Handle_Cb func, + const void *data) +{ + Efl_Loop_Data *pd = ML_DAT; Ecore_Win32_Handler *wh; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); @@ -1467,45 +1398,19 @@ ecore_main_win32_handler_add(void *h, wh = ecore_win32_handler_calloc(1); if (!wh) return NULL; ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER); + wh->loop = obj; + wh->loop_data = pd; wh->h = (HANDLE)h; - wh->delete_me = EINA_FALSE; wh->func = func; wh->data = (void *)data; - win32_handlers = (Ecore_Win32_Handler *) - eina_inlist_append(EINA_INLIST_GET(win32_handlers), + pd->win32_handlers = (Ecore_Win32_Handler *) + eina_inlist_append(EINA_INLIST_GET(pd->win32_handlers), EINA_INLIST_GET(wh)); return wh; } -#else -EAPI Ecore_Win32_Handler * -ecore_main_win32_handler_add(void *h EINA_UNUSED, - Ecore_Win32_Handle_Cb func EINA_UNUSED, - const void *data EINA_UNUSED) -{ - return NULL; -} - -#endif - -EAPI void * -ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) -{ - if (!fd_handler) return NULL; - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - - if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) - { - ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, - "ecore_main_fd_handler_del"); - return NULL; - } - return _ecore_main_fd_handler_del(fd_handler); -} - -#ifdef _WIN32 -static void * -_ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler) +void * +_ecore_main_win32_handler_del(Eo *obj, Efl_Loop_Data *pd, Ecore_Win32_Handler *win32_handler) { if (win32_handler->delete_me) { @@ -1514,10 +1419,22 @@ _ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler) } win32_handler->delete_me = EINA_TRUE; - win32_handlers_to_delete = eina_list_append(win32_handlers_to_delete, win32_handler); + win32_handler->handler = NULL; + pd->win32_handlers_to_delete = eina_list_append + (pd->win32_handlers_to_delete, win32_handler); return win32_handler->data; } +EAPI Ecore_Win32_Handler * +ecore_main_win32_handler_add(void *h, + Ecore_Win32_Handle_Cb func, + const void *data) +{ + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + return _ecore_main_win32_handler_add(efl_loop_main_get(EFL_LOOP_CLASS), + ML_DAT, NULL, func, data); +} + EAPI void * ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler) { @@ -1531,17 +1448,42 @@ ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler) "ecore_main_win32_handler_del"); return NULL; } - ret = _ecore_main_win32_handler_del(win32_handler); + ret = _ecore_main_win32_handler_del(ML_OBJ, ML_DAT, win32_handler); return ret; } - #else +EAPI Ecore_Win32_Handler * +_ecore_main_win32_handler_add(Eo *obj EINA_UNUSED, + Efl_Loop_Data *pd EINA_UNUSED, + Eo *handler EINA_UNUSED, + void *h EINA_UNUSED, + Ecore_Win32_Handle_Cb func EINA_UNUSED, + const void *data EINA_UNUSED) +{ + return NULL; +} + +void * +_ecore_main_win32_handler_del(Eo *obj EINA_UNUSED, + Efl_Loop_Data *pd EINA_UNUSED, + Ecore_Win32_Handler *win32_handler EINA_UNUSED) +{ + return NULL; +} + +EAPI Ecore_Win32_Handler * +ecore_main_win32_handler_add(void *h EINA_UNUSED, + Ecore_Win32_Handle_Cb func EINA_UNUSED, + const void *data EINA_UNUSED) +{ + return NULL; +} + EAPI void * ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler EINA_UNUSED) { return NULL; } - #endif EAPI void @@ -1549,20 +1491,23 @@ ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data) { + Efl_Loop_Data *pd = fd_handler->loop_data; EINA_MAIN_LOOP_CHECK_RETURN; if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) { ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, "ecore_main_fd_handler_prepare_callback_set"); - return ; + return; } fd_handler->prep_func = func; fd_handler->prep_data = (void *)data; - if ((!fd_handlers_with_prep) || - (fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler)))) - /* FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! */ - fd_handlers_with_prep = eina_list_append(fd_handlers_with_prep, fd_handler); + if ((!pd->fd_handlers_with_prep) || + (pd->fd_handlers_with_prep && + (!eina_list_data_find(pd->fd_handlers_with_prep, fd_handler)))) + // FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! + pd->fd_handlers_with_prep = eina_list_append + (pd->fd_handlers_with_prep, fd_handler); } EAPI int @@ -1593,7 +1538,7 @@ ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, "ecore_main_fd_handler_active_get"); return EINA_FALSE; } - if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE; + if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE; if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE; if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE; return ret; @@ -1603,99 +1548,117 @@ EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags) { - int ret; - - EINA_MAIN_LOOP_CHECK_RETURN; + int ret = -1; if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)) { ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER, "ecore_main_fd_handler_active_set"); - return ; + return; } fd_handler->flags = flags; - ret = _ecore_main_fdh_poll_modify(fd_handler); + if (fd_handler->loop_data) + ret = _ecore_main_fdh_poll_modify(fd_handler->loop_data, fd_handler); if (ret < 0) - { - ERR("Failed to mod epoll fd %d: %s!", fd_handler->fd, strerror(errno)); - } + ERR("Failed to mod epoll fd %d, loop data=%p: %s!", + fd_handler->fd, fd_handler->loop_data, strerror(errno)); } void -_ecore_main_shutdown(void) +_ecore_main_content_clear(Efl_Loop_Data *pd) { Efl_Promise *promise; Efl_Future *future; - if (in_main_loop) - { - ERR("\n" - "*** ECORE WARNING: Calling ecore_shutdown() while still in the main loop.\n" - "*** Program may crash or behave strangely now."); - return; - } - - EINA_LIST_FREE(_pending_futures, future) + EINA_LIST_FREE(pd->pending_futures, future) efl_del(future); - - EINA_LIST_FREE(_pending_promises, promise) + Eina_List *tmp = pd->pending_promises; + pd->pending_promises = NULL; + EINA_LIST_FREE(tmp, promise) ecore_loop_promise_fulfill(promise); - while (fd_handlers) + while (pd->fd_handlers) { - Ecore_Fd_Handler *fdh; + Ecore_Fd_Handler *fdh = pd->fd_handlers; - fdh = fd_handlers; - fd_handlers = (Ecore_Fd_Handler *)eina_inlist_remove(EINA_INLIST_GET(fd_handlers), - EINA_INLIST_GET(fdh)); - ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); - ecore_fd_handler_mp_free(fdh); + pd->fd_handlers = (Ecore_Fd_Handler *) + eina_inlist_remove(EINA_INLIST_GET(pd->fd_handlers), + EINA_INLIST_GET(fdh)); + if (fdh->handler) efl_del(fdh->handler); + else + { + ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); + ecore_fd_handler_mp_free(fdh); + } + } + if (pd) + { + if (pd->fd_handlers_with_buffer) + pd->fd_handlers_with_buffer = + eina_list_free(pd->fd_handlers_with_buffer); + if (pd->fd_handlers_with_prep) + pd->fd_handlers_with_prep = + eina_list_free(pd->fd_handlers_with_prep); + if (pd->file_fd_handlers) + pd->file_fd_handlers = + eina_list_free(pd->file_fd_handlers); + if (pd->fd_handlers_to_delete) + pd->fd_handlers_to_delete = + eina_list_free(pd->fd_handlers_to_delete); + pd->fd_handlers_to_call = NULL; + pd->fd_handlers_to_call_current = NULL; } - if (fd_handlers_with_buffer) - fd_handlers_with_buffer = eina_list_free(fd_handlers_with_buffer); - if (fd_handlers_with_prep) - fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep); - if (fd_handlers_to_delete) - fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete); - if (file_fd_handlers) - file_fd_handlers = eina_list_free(file_fd_handlers); - - fd_handlers_to_call = NULL; - fd_handlers_to_call_current = NULL; - fd_handlers_to_delete = NULL; - fd_handler_current = NULL; - do_quit = 0; + + pd->do_quit = 0; #ifdef _WIN32 - while (win32_handlers) + while (pd->win32_handlers) { - Ecore_Win32_Handler *wh; + Ecore_Win32_Handler *wh = pd->win32_handlers; - wh = win32_handlers; - win32_handlers = (Ecore_Win32_Handler *)eina_inlist_remove(EINA_INLIST_GET(win32_handlers), - EINA_INLIST_GET(wh)); - ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE); - ecore_win32_handler_mp_free(wh); + pd->win32_handlers = (Ecore_Win32_Handler *) + eina_inlist_remove(EINA_INLIST_GET(pd->win32_handlers), + EINA_INLIST_GET(wh)); + if (fdh->handler) efl_del(fdh->handler); + else + { + ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE); + ecore_win32_handler_mp_free(wh); + } } - if (win32_handlers_to_delete) - win32_handlers_to_delete = eina_list_free(win32_handlers_to_delete); - win32_handlers_to_delete = NULL; - win32_handler_current = NULL; + if (pd->win32_handlers_to_delete) + pd->win32_handlers_to_delete = + eina_list_free(pd->win32_handlers_to_delete); + pd->win32_handler_current = NULL; #endif } +void +_ecore_main_shutdown(void) +{ + Efl_Loop_Data *pd = ML_DAT; + + if (pd->in_loop) + { + ERR("Calling ecore_shutdown() while still in the main loop!!!"); + return; + } + _ecore_main_content_clear(pd); +} + static void -_ecore_main_prepare_handlers(void) +_ecore_main_prepare_handlers(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd) { Ecore_Fd_Handler *fdh; Eina_List *l, *l2; - /* call the prepare callback for all handlers with prep functions */ - EINA_LIST_FOREACH_SAFE(fd_handlers_with_prep, l, l2, fdh) + // call the prepare callback for all handlers with prep functions + EINA_LIST_FOREACH_SAFE(pd->fd_handlers_with_prep, l, l2, fdh) { if (!fdh) { - fd_handlers_with_prep = eina_list_remove_list(l, fd_handlers_with_prep); + pd->fd_handlers_with_prep = eina_list_remove_list + (l, pd->fd_handlers_with_prep); continue; } if (!fdh->delete_me && fdh->prep_func) @@ -1705,13 +1668,14 @@ _ecore_main_prepare_handlers(void) fdh->references--; } else - fd_handlers_with_prep = eina_list_remove_list(fd_handlers_with_prep, l); + pd->fd_handlers_with_prep = eina_list_remove_list + (pd->fd_handlers_with_prep, l); } } #if !defined(USE_G_MAIN_LOOP) static int -_ecore_main_select(double timeout) +_ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout) { struct timeval tv, *t; fd_set rfds, wfds, exfds; @@ -1720,8 +1684,8 @@ _ecore_main_select(double timeout) int max_fd, ret, err_no; t = NULL; - if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0))) /* finite() tests for NaN, too big, too small, and infinity. */ - { + if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0))) + { // finite() tests for NaN, too big, too small, and infinity. tv.tv_sec = 0; tv.tv_usec = 0; t = &tv; @@ -1747,15 +1711,14 @@ _ecore_main_select(double timeout) FD_ZERO(&wfds); FD_ZERO(&exfds); - /* call the prepare callback for all handlers */ - if (fd_handlers_with_prep) - _ecore_main_prepare_handlers(); + // call the prepare callback for all handlers + if (pd->fd_handlers_with_prep) _ecore_main_prepare_handlers(obj, pd); #ifdef HAVE_EPOLL - if (epoll_fd < 0) + if (pd->epoll_fd < 0) { #endif - EINA_INLIST_FOREACH(fd_handlers, fdh) + EINA_INLIST_FOREACH(pd->fd_handlers, fdh) { if (!fdh->delete_me) { @@ -1780,87 +1743,91 @@ _ecore_main_select(double timeout) #ifdef HAVE_EPOLL else { - /* polling on the epoll fd will wake when an fd in the epoll set is active */ - max_fd = _ecore_get_epoll_fd(); - FD_SET(max_fd, &rfds); - } -#endif - EINA_LIST_FOREACH(file_fd_handlers, l, fdh) - if (!fdh->delete_me) - { - if (fdh->flags & ECORE_FD_READ) - { - FD_SET(fdh->fd, &rfds); - if (fdh->fd > max_fd) max_fd = fdh->fd; - } - if (fdh->flags & ECORE_FD_WRITE) - { - FD_SET(fdh->fd, &wfds); - if (fdh->fd > max_fd) max_fd = fdh->fd; - } - if (fdh->flags & ECORE_FD_ERROR) - { - FD_SET(fdh->fd, &exfds); - if (fdh->fd > max_fd) max_fd = fdh->fd; - } - if (fdh->fd > max_fd) max_fd = fdh->fd; - } - if (_ecore_signal_count_get()) return -1; + // polling on the epoll fd will wake when fd in the epoll set is active + max_fd = _ecore_get_epoll_fd(obj, pd); + FD_SET(max_fd, &rfds); + } +#endif + EINA_LIST_FOREACH(pd->file_fd_handlers, l, fdh) + { + if (!fdh->delete_me) + { + if (fdh->flags & ECORE_FD_READ) + { + FD_SET(fdh->fd, &rfds); + if (fdh->fd > max_fd) max_fd = fdh->fd; + } + if (fdh->flags & ECORE_FD_WRITE) + { + FD_SET(fdh->fd, &wfds); + if (fdh->fd > max_fd) max_fd = fdh->fd; + } + if (fdh->flags & ECORE_FD_ERROR) + { + FD_SET(fdh->fd, &exfds); + if (fdh->fd > max_fd) max_fd = fdh->fd; + } + if (fdh->fd > max_fd) max_fd = fdh->fd; + } + } + if (_ecore_signal_count_get(obj, pd)) return -1; eina_evlog("<RUN", NULL, 0.0, NULL); eina_evlog("!SLEEP", NULL, 0.0, t ? "timeout" : "forever"); - ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t); + if (obj == ML_OBJ) + ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t); + else + ret = general_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t); err_no = errno; eina_evlog("!WAKE", NULL, 0.0, NULL); eina_evlog(">RUN", NULL, 0.0, NULL); - _ecore_time_loop_time = ecore_time_get(); + pd->loop_time = ecore_time_get(); if (ret < 0) { #ifndef _WIN32 if (err_no == EINTR) return -1; - else if (err_no == EBADF) - _ecore_main_fd_handlers_bads_rem(); + else if (err_no == EBADF) _ecore_main_fd_handlers_bads_rem(obj, pd); #endif } if (ret > 0) { #ifdef HAVE_EPOLL - if (epoll_fd >= 0) - _ecore_main_fdh_epoll_mark_active(); + if (pd->epoll_fd >= 0) + _ecore_main_fdh_epoll_mark_active(obj, pd); else #endif { - EINA_INLIST_FOREACH(fd_handlers, fdh) + EINA_INLIST_FOREACH(pd->fd_handlers, fdh) { if (!fdh->delete_me) { if (FD_ISSET(fdh->fd, &rfds)) - fdh->read_active = EINA_TRUE; + 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); + _ecore_try_add_to_call_list(obj, pd, fdh); } } } - EINA_LIST_FOREACH(file_fd_handlers, l, fdh) + EINA_LIST_FOREACH(pd->file_fd_handlers, l, fdh) { if (!fdh->delete_me) { if (FD_ISSET(fdh->fd, &rfds)) - fdh->read_active = EINA_TRUE; + 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); + _ecore_try_add_to_call_list(obj, pd, fdh); } } - _ecore_main_fd_handlers_cleanup(); + _ecore_main_fd_handlers_cleanup(obj, pd); #ifdef _WIN32 - _ecore_main_win32_handlers_cleanup(); + _ecore_main_win32_handlers_cleanup(obj, pd); #endif return 1; } @@ -1872,14 +1839,14 @@ _ecore_main_select(double timeout) #ifndef _WIN32 # ifndef USE_G_MAIN_LOOP static void -_ecore_main_fd_handlers_bads_rem(void) +_ecore_main_fd_handlers_bads_rem(Eo *obj, Efl_Loop_Data *pd) { Ecore_Fd_Handler *fdh; Eina_Inlist *l; int found = 0; ERR("Removing bad fds"); - for (l = EINA_INLIST_GET(fd_handlers); l; ) + for (l = EINA_INLIST_GET(pd->fd_handlers); l; ) { fdh = (Ecore_Fd_Handler *)l; l = l->next; @@ -1898,8 +1865,9 @@ _ecore_main_fd_handlers_bads_rem(void) if (!fdh->delete_me) { fdh->delete_me = EINA_TRUE; - _ecore_main_fdh_poll_del(fdh); - fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh); + _ecore_main_fdh_poll_del(pd, fdh); + pd->fd_handlers_to_delete = + eina_list_append(pd->fd_handlers_to_delete, fdh); } found++; } @@ -1907,12 +1875,14 @@ _ecore_main_fd_handlers_bads_rem(void) } else { - ERR("Problematic fd found at %d! setting it for delete", fdh->fd); + ERR("Problematic fd found at %d! setting it for delete", + fdh->fd); if (!fdh->delete_me) { fdh->delete_me = EINA_TRUE; - _ecore_main_fdh_poll_del(fdh); - fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh); + _ecore_main_fdh_poll_del(pd, fdh); + pd->fd_handlers_to_delete = + eina_list_append(pd->fd_handlers_to_delete, fdh); } found++; @@ -1927,170 +1897,171 @@ _ecore_main_fd_handlers_bads_rem(void) ERR("No bad fd found. EEEK!"); # endif } - _ecore_main_fd_handlers_cleanup(); + _ecore_main_fd_handlers_cleanup(obj, pd); } # endif #endif static void -_ecore_main_fd_handlers_cleanup(void) +_ecore_main_fd_handlers_cleanup(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd) { Ecore_Fd_Handler *fdh, *last; Eina_List *l, *l2; - if (!fd_handlers_to_delete) return; - // Cleanup deleted caller from the list last = NULL; - fdh = fd_handlers_to_call; + fdh = pd->fd_handlers_to_call; while (fdh) { if (fdh->delete_me) { if (!last) - fd_handlers_to_call = fdh == fdh->next_ready ? NULL : fdh->next_ready; + pd->fd_handlers_to_call = fdh == fdh->next_ready ? + NULL : fdh->next_ready; else - last->next_ready = fdh == fdh->next_ready ? last : fdh->next_ready; - } - else - { - last = fdh; + last->next_ready = fdh == fdh->next_ready ? + last : fdh->next_ready; } + else last = fdh; - if (fdh == fdh->next_ready) - break; + if (fdh == fdh->next_ready) break; fdh = fdh->next_ready; } - EINA_LIST_FOREACH_SAFE(fd_handlers_to_delete, l, l2, fdh) + if (!pd->fd_handlers_to_delete) return; + EINA_LIST_FOREACH_SAFE(pd->fd_handlers_to_delete, l, l2, fdh) { if (!fdh) { - fd_handlers_to_delete = eina_list_remove_list(l, fd_handlers_to_delete); + pd->fd_handlers_to_delete = eina_list_remove_list + (l, pd->fd_handlers_to_delete); continue; } - /* fdh->delete_me should be set for all fdhs at the start of the list */ - if (fdh->references) - continue; - if (fd_handlers_to_call_current == fdh) - fd_handlers_to_call_current = NULL; - if (fdh->buf_func && fd_handlers_with_buffer) - fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fdh); - if (fdh->prep_func && fd_handlers_with_prep) - fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fdh); - fd_handlers = (Ecore_Fd_Handler *) - eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh)); + if (fdh->references) continue; + if (pd->fd_handlers_to_call_current == fdh) + pd->fd_handlers_to_call_current = NULL; + if (fdh->buf_func && pd->fd_handlers_with_buffer) + pd->fd_handlers_with_buffer = eina_list_remove + (pd->fd_handlers_with_buffer, fdh); + if (fdh->prep_func && pd->fd_handlers_with_prep) + pd->fd_handlers_with_prep = eina_list_remove + (pd->fd_handlers_with_prep, fdh); + pd->fd_handlers = (Ecore_Fd_Handler *) + eina_inlist_remove(EINA_INLIST_GET(pd->fd_handlers), + EINA_INLIST_GET(fdh)); if (fdh->file) - file_fd_handlers = eina_list_remove(file_fd_handlers, fdh); + pd->file_fd_handlers = eina_list_remove(pd->file_fd_handlers, fdh); ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); ecore_fd_handler_mp_free(fdh); - fd_handlers_to_delete = eina_list_remove_list(fd_handlers_to_delete, l); + pd->fd_handlers_to_delete = eina_list_remove_list + (pd->fd_handlers_to_delete, l); } } #ifdef _WIN32 static void -_ecore_main_win32_handlers_cleanup(void) +_ecore_main_win32_handlers_cleanup(Eo *obj, Efl_Loop_Data *pd) { Ecore_Win32_Handler *wh; - Eina_List *l; - Eina_List *l2; + Eina_List *l, *l2; - if (!win32_handlers_to_delete) return; - EINA_LIST_FOREACH_SAFE(win32_handlers_to_delete, l, l2, wh) + if (!pd->win32_handlers_to_delete) return; + EINA_LIST_FOREACH_SAFE(pd->win32_handlers_to_delete, l, l2, wh) { if (!wh) { - win32_handlers_to_delete = eina_list_remove_list(l, win32_handlers_to_delete); + pd->win32_handlers_to_delete = eina_list_remove_list + (l, pd->win32_handlers_to_delete); continue; } - /* wh->delete_me should be set for all whs at the start of the list */ - if (wh->references) - continue; - win32_handlers = (Ecore_Win32_Handler *) - eina_inlist_remove(EINA_INLIST_GET(win32_handlers), EINA_INLIST_GET(wh)); + // wh->delete_me should be set for all whs at the start of the list + if (wh->references) continue; + pd->win32_handlers = (Ecore_Win32_Handler *) + eina_inlist_remove(EINA_INLIST_GET(pd->win32_handlers), + EINA_INLIST_GET(wh)); ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE); ecore_win32_handler_mp_free(wh); - win32_handlers_to_delete = eina_list_remove_list(win32_handlers_to_delete, l); + pd->win32_handlers_to_delete = eina_list_remove_list + (pd->win32_handlers_to_delete, l); } } - #endif static void -_ecore_main_fd_handlers_call(void) +_ecore_main_fd_handlers_call(Eo *obj, Efl_Loop_Data *pd) { - /* grab a new list */ - if (!fd_handlers_to_call_current) - { - fd_handlers_to_call_current = fd_handlers_to_call; - fd_handlers_to_call = NULL; - } + // grab a new list + if (!pd->fd_handlers_to_call_current) + { + pd->fd_handlers_to_call_current = pd->fd_handlers_to_call; + pd->fd_handlers_to_call = NULL; + } - if (!fd_handlers_to_call_current) return; + if (!pd->fd_handlers_to_call_current) return; eina_evlog("+fd_handlers", NULL, 0.0, NULL); - while (fd_handlers_to_call_current) - { - Ecore_Fd_Handler *fdh = fd_handlers_to_call_current; - - if (!fdh->delete_me) - { - if ((fdh->read_active) || - (fdh->write_active) || - (fdh->error_active)) - { - fdh->references++; - if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh)) - { - if (!fdh->delete_me) - { - fdh->delete_me = EINA_TRUE; - _ecore_main_fdh_poll_del(fdh); - fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh); - } - } - fdh->references--; + while (pd->fd_handlers_to_call_current) + { + Ecore_Fd_Handler *fdh = pd->fd_handlers_to_call_current; + + if (!fdh->delete_me) + { + if ((fdh->read_active) || + (fdh->write_active) || + (fdh->error_active)) + { + fdh->references++; + if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh)) + { + if (!fdh->delete_me) + { + fdh->delete_me = EINA_TRUE; + _ecore_main_fdh_poll_del(pd, fdh); + pd->fd_handlers_to_delete = eina_list_append + (pd->fd_handlers_to_delete, fdh); + } + } + fdh->references--; #ifdef EFL_EXTRA_SANITY_CHECKS - _ecore_fd_valid(); + _ecore_fd_valid(obj, pd); #endif + fdh->read_active = EINA_FALSE; + fdh->write_active = EINA_FALSE; + fdh->error_active = EINA_FALSE; + } + } - fdh->read_active = EINA_FALSE; - fdh->write_active = EINA_FALSE; - fdh->error_active = EINA_FALSE; - } - } - - /* stop when we point to ourselves */ - if (fdh->next_ready == fdh) - { - fdh->next_ready = NULL; - fd_handlers_to_call_current = NULL; - break; - } + // stop when we point to ourselves + if (fdh->next_ready == fdh) + { + fdh->next_ready = NULL; + pd->fd_handlers_to_call_current = NULL; + break; + } - fd_handlers_to_call_current = fdh->next_ready; - fdh->next_ready = NULL; + pd->fd_handlers_to_call_current = fdh->next_ready; + fdh->next_ready = NULL; } eina_evlog("-fd_handlers", NULL, 0.0, NULL); } static int -_ecore_main_fd_handlers_buf_call(void) +_ecore_main_fd_handlers_buf_call(Eo *obj, Efl_Loop_Data *pd) { Ecore_Fd_Handler *fdh; Eina_List *l, *l2; int ret; - if (!fd_handlers_with_buffer) return 0; + if (!pd->fd_handlers_with_buffer) return 0; eina_evlog("+fd_handlers_buf", NULL, 0.0, NULL); ret = 0; - EINA_LIST_FOREACH_SAFE(fd_handlers_with_buffer, l, l2, fdh) + EINA_LIST_FOREACH_SAFE(pd->fd_handlers_with_buffer, l, l2, fdh) { if (!fdh) { - fd_handlers_with_buffer = eina_list_remove_list(l, fd_handlers_with_buffer); + pd->fd_handlers_with_buffer = eina_list_remove_list + (l, pd->fd_handlers_with_buffer); continue; } if ((!fdh->delete_me) && fdh->buf_func) @@ -2100,12 +2071,13 @@ _ecore_main_fd_handlers_buf_call(void) { ret |= _ecore_call_fd_cb(fdh->func, fdh->data, fdh); fdh->read_active = EINA_TRUE; - _ecore_try_add_to_call_list(fdh); + _ecore_try_add_to_call_list(obj, pd, fdh); } fdh->references--; } else - fd_handlers_with_buffer = eina_list_remove_list(fd_handlers_with_buffer, l); + pd->fd_handlers_with_buffer = eina_list_remove_list + (pd->fd_handlers_with_buffer, l); } eina_evlog("-fd_handlers_buf", NULL, 0.0, NULL); return ret; @@ -2113,111 +2085,107 @@ _ecore_main_fd_handlers_buf_call(void) #ifdef HAVE_LIBUV static void -_ecore_main_loop_uv_prepare(uv_prepare_t* handle EINA_UNUSED) +_ecore_main_loop_uv_prepare(uv_prepare_t *handle EINA_UNUSED) { + Eo *obj = ML_OBJ; + Efl_Loop_Data *pd = ML_DAT; + double t = -1; + _dl_uv_timer_stop(&_ecore_main_uv_handle_timers); - if(in_main_loop == 0 && do_quit) - { - _ecore_main_fd_handlers_cleanup(); - - while (fd_handlers) - { - Ecore_Fd_Handler *fdh; - - fdh = fd_handlers; - fd_handlers = (Ecore_Fd_Handler *)eina_inlist_remove(EINA_INLIST_GET(fd_handlers), - EINA_INLIST_GET(fdh)); - fdh->delete_me = 1; - _ecore_main_fdh_poll_del(fdh); - ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); - ecore_fd_handler_mp_free(fdh); - } - if (fd_handlers_with_buffer) - fd_handlers_with_buffer = eina_list_free(fd_handlers_with_buffer); - if (fd_handlers_with_prep) - fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep); - if (fd_handlers_to_delete) - fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete); - if (file_fd_handlers) - file_fd_handlers = eina_list_free(file_fd_handlers); - - fd_handlers_to_call = NULL; - fd_handlers_to_call_current = NULL; - fd_handlers_to_delete = NULL; - fd_handler_current = NULL; - - _dl_uv_prepare_stop(&_ecore_main_uv_prepare); - _dl_uv_check_stop(&_ecore_main_uv_check); - _dl_uv_stop(_dl_uv_default_loop()); - - return; + if ((pd->in_loop == 0) && (pd->do_quit)) + { + _ecore_main_fd_handlers_cleanup(obj, pd); + + while (pd->fd_handlers) + { + Ecore_Fd_Handler *fdh = pd->fd_handlers; + pd->fd_handlers = (Ecore_Fd_Handler *) + eina_inlist_remove(EINA_INLIST_GET(pd->fd_handlers), + EINA_INLIST_GET(fdh)); + fdh->delete_me = 1; + _ecore_main_fdh_poll_del(pd, fdh); + ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE); + ecore_fd_handler_mp_free(fdh); + } + if (pd->fd_handlers_with_buffer) + pd->fd_handlers_with_buffer = eina_list_free(pd->fd_handlers_with_buffer); + if (pd->fd_handlers_with_prep) + pd->fd_handlers_with_prep = eina_list_free(pd->fd_handlers_with_prep); + if (pd->fd_handlers_to_delete) + pd->fd_handlers_to_delete = eina_list_free(pd->fd_handlers_to_delete); + if (pd->file_fd_handlers) + pd->file_fd_handlers = eina_list_free(pd->file_fd_handlers); + + pd->fd_handlers_to_call = NULL; + pd->fd_handlers_to_call_current = NULL; + + _dl_uv_prepare_stop(&_ecore_main_uv_prepare); + _dl_uv_check_stop(&_ecore_main_uv_check); + _dl_uv_stop(_dl_uv_default_loop()); + + return; } in_main_loop++; + pd->in_loop = in_main_loop; - if(!_ecore_main_uv_idling) + if (!_ecore_main_uv_idling) { _ecore_main_uv_idling = EINA_TRUE; - _ecore_idle_enterer_call(_mainloop_singleton); + _ecore_idle_enterer_call(obj); _ecore_throttle(); + _throttle_do(pd); } - double t = -1; - if(_ecore_main_uv_idling) + if (_ecore_main_uv_idling) { - _ecore_idler_all_call(_mainloop_singleton); - DBG("called idles"); - if(_ecore_idler_exist(_mainloop_singleton) || _ecore_event_exist()) - t = 0.0; + _ecore_idler_all_call(obj); + DBG("called idles"); + if (_ecore_idler_exist(_obj) || efl_loop_message_exists(obj)) t = 0.0; } - if (do_quit) + if (pd->do_quit) { - DBG("do quit outside loop"); - - if(_ecore_main_uv_idling) - { - _ecore_idle_exiter_call(_mainloop_singleton); - _ecore_animator_run_reset(); - - _ecore_main_uv_idling = EINA_FALSE; - } + DBG("do quit outside loop"); - t = -1; - - _ecore_time_loop_time = ecore_time_get(); - _efl_loop_timer_enable_new(); - - goto done; + if (_ecore_main_uv_idling) + { + _ecore_idle_exiter_call(obj); + _ecore_animator_run_reset(); + _ecore_main_uv_idling = EINA_FALSE; + } + t = -1; + pd->loop_time = ecore_time_get(); + _efl_loop_timer_enable_new(obj, pd); + goto done; } - assert(!fd_handlers_to_call); + assert(!pd->fd_handlers_to_call); - _ecore_time_loop_time = ecore_time_get(); - _efl_loop_timer_enable_new(); - if (_efl_loop_timers_exists() || t >= 0) + pd->loop_time = ecore_time_get(); + _efl_loop_timer_enable_new(obj, pd); + if (_efl_loop_timers_exists(obj, pd) || (t >= 0)) { - double tnext = _efl_loop_timer_next_get(); - if (t < 0 || (tnext >= 0 && tnext < t)) t = tnext; - DBG("Should awake after %f", t); - - if (t >= 0.0) - { - //_dl_uv_timer_stop(&_ecore_main_uv_handle_timers); - _dl_uv_timer_start(&_ecore_main_uv_handle_timers, &_ecore_main_loop_timer_run, t * 1000 - , 0); - } - else - DBG("Is not going to awake with timer"); - } - else - DBG("Is not going to awake with timer"); + double tnext = _efl_loop_timer_next_get(obj, pd); + + if ((t < 0) || ((tnext >= 0) && (tnext < t))) t = tnext; + DBG("Should awake after %f", t); - done: - if (fd_handlers_with_prep) - _ecore_main_prepare_handlers(); + if (t >= 0.0) + { + // _dl_uv_timer_stop(&_ecore_main_uv_handle_timers); + _dl_uv_timer_start(&_ecore_main_uv_handle_timers, + &_ecore_main_loop_timer_run, + t * 1000, 0); + } + else DBG("Is not going to awake with timer"); + } + else DBG("Is not going to awake with timer"); +done: + if (pd->fd_handlers_with_prep) _ecore_main_prepare_handlers(obj, pd); in_main_loop--; + pd->in_loop = in_main_loop; } #endif @@ -2229,56 +2197,57 @@ enum { }; static int -_ecore_main_loop_spin_core(void) -{ - /* as we are spinning we need to update loop time per spin */ - _ecore_time_loop_time = ecore_time_get(); - /* call all idlers */ - _ecore_idler_all_call(_mainloop_singleton); - /* which returns false if no more idelrs exist */ - if (!_ecore_idler_exist(_mainloop_singleton)) return SPIN_RESTART; - /* sneaky - drop through or if checks - the first one to succeed - * drops through and returns "continue" so further ones dont run */ - if ((_ecore_main_select(0.0) > 0) || (_ecore_event_exist()) || - (_ecore_signal_count_get() > 0) || (do_quit)) - return LOOP_CONTINUE; - /* default - spin more */ - return SPIN_MORE; +_ecore_main_loop_spin_core(Eo *obj, Efl_Loop_Data *pd) +{ + // as we are spinning we need to update loop time per spin + pd->loop_time = ecore_time_get(); + // call all idlers + _ecore_idler_all_call(obj); + // which returns false if no more idelrs exist + if (!_ecore_idler_exist(obj)) return SPIN_RESTART; + // sneaky - drop through or if checks - the first one to succeed + // drops through and returns "continue" so further ones dont run + if ((_ecore_main_select(obj, pd, 0.0) > 0) || + (efl_loop_message_exists(obj)) || + (_ecore_signal_count_get(obj, pd) > 0) || (pd->do_quit)) + return LOOP_CONTINUE; + // default - spin more + return SPIN_MORE; } static int -_ecore_main_loop_spin_no_timers(void) -{ - /* if we have idlers we HAVE to spin and handle everything - * in a polling way - spin in a tight polling loop */ - for (;; ) - { - int action = _ecore_main_loop_spin_core(); - if (action != SPIN_MORE) return action; - /* if an idler has added a timer then we need to go through - * the start of the spin cycle again to handle cases properly */ - if (_efl_loop_timers_exists()) return SPIN_RESTART; - } - /* just contiune handling events etc. */ - return LOOP_CONTINUE; +_ecore_main_loop_spin_no_timers(Eo *obj, Efl_Loop_Data *pd) +{ + // if we have idlers we HAVE to spin and handle everything + // in a polling way - spin in a tight polling loop + for (;;) + { + int action = _ecore_main_loop_spin_core(obj, pd); + if (action != SPIN_MORE) return action; + // if an idler has added a timer then we need to go through + // the start of the spin cycle again to handle cases properly + if (_efl_loop_timers_exists(obj, pd)) return SPIN_RESTART; + } + // just contiune handling events etc. + return LOOP_CONTINUE; } static int -_ecore_main_loop_spin_timers(void) -{ - /* if we have idlers we HAVE to spin and handle everything - * in a polling way - spin in a tight polling loop */ - for (;; ) - { - int action = _ecore_main_loop_spin_core(); - if (action != SPIN_MORE) return action; - /* if next timer expires now or in the past - stop spinning and - * continue the mainloop walk as our "select" timeout has - * expired now */ - if (_efl_loop_timer_next_get() <= 0.0) return LOOP_CONTINUE; - } - /* just contiune handling events etc. */ - return LOOP_CONTINUE; +_ecore_main_loop_spin_timers(Eo *obj, Efl_Loop_Data *pd) +{ + // if we have idlers we HAVE to spin and handle everything + // in a polling way - spin in a tight polling loop + for (;;) + { + int action = _ecore_main_loop_spin_core(obj, pd); + if (action != SPIN_MORE) return action; + // if next timer expires now or in the past - stop spinning and + // continue the mainloop walk as our "select" timeout has + // expired now + if (_efl_loop_timer_next_get(obj, pd) <= 0.0) return LOOP_CONTINUE; + } + // just contiune handling events etc. + return LOOP_CONTINUE; } static void @@ -2297,163 +2266,168 @@ _ecore_fps_marker_2(void) } static void -_ecore_main_loop_iterate_internal(int once_only) +_ecore_main_loop_iterate_internal(Eo *obj, Efl_Loop_Data *pd, int once_only) { double next_time = -1.0; Eo *f, *p; - in_main_loop++; - - /* destroy all optional futures */ - EINA_LIST_FREE(_pending_futures, f) - efl_del(f); - - /* and propagate all promise value */ - EINA_LIST_FREE(_pending_promises, p) - ecore_loop_promise_fulfill(p); - - /* expire any timers */ - _efl_loop_timer_expired_timers_call(_ecore_time_loop_time); - - /* process signals into events .... */ - _ecore_signal_received_process(); - /* if as a result of timers/animators or signals we have accumulated - * events, then instantly handle them */ - if (_ecore_event_exist()) - { - /* but first conceptually enter an idle state */ - _ecore_idle_enterer_call(_mainloop_singleton); + if (obj == ML_OBJ) + { + in_main_loop++; + pd->in_loop = in_main_loop; + } + // destroy all optional futures + EINA_LIST_FREE(pd->pending_futures, f) efl_del(f); + // and propagate all promise value + Eina_List *tmp = pd->pending_promises; + pd->pending_promises = NULL; + EINA_LIST_FREE(tmp, p) ecore_loop_promise_fulfill(p); + // expire any timers + _efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time); + // process signals into events .... + if (obj == ML_OBJ) _ecore_signal_received_process(obj, pd); + // if as a result of timers/animators or signals we have accumulated + // events, then instantly handle them + if (efl_loop_message_exists(obj)) + { + // but first conceptually enter an idle state + _ecore_idle_enterer_call(obj); _ecore_throttle(); - /* now quickly poll to see which input fd's are active */ - _ecore_main_select(0.0); - /* allow newly queued timers to expire from now on */ - _efl_loop_timer_enable_new(); - /* go straight to processing the events we had queued */ + _throttle_do(pd); + // now quickly poll to see which input fd's are active + _ecore_main_select(obj, pd, 0.0); + // allow newly queued timers to expire from now on + _efl_loop_timer_enable_new(obj, pd); + // go straight to processing the events we had queued goto process_all; } if (once_only) { - /* in once_only mode we should quickly poll for inputs, signals - * if we got any events or signals, allow new timers to process. - * use bitwise or to force both conditions to be tested and - * merged together */ - if (_ecore_main_select(0.0) | _ecore_signal_count_get()) + // in once_only mode we should quickly poll for inputs, signals + // if we got any events or signals, allow new timers to process. + // use bitwise or to force both conditions to be tested and + // merged together + if (_ecore_main_select(obj, pd, 0.0) | + _ecore_signal_count_get(obj, pd)) { - _efl_loop_timer_enable_new(); + _efl_loop_timer_enable_new(obj, pd); goto process_all; } } else { - /* call idle enterers ... */ - _ecore_idle_enterer_call(_mainloop_singleton); + // call idle enterers ... + _ecore_idle_enterer_call(obj); _ecore_throttle(); + _throttle_do(pd); } - /* if these calls caused any buffered events to appear - deal with them */ - if (fd_handlers_with_buffer) - _ecore_main_fd_handlers_buf_call(); + // if these calls caused any buffered events to appear - deal with them + if (pd->fd_handlers_with_buffer) + _ecore_main_fd_handlers_buf_call(obj, pd); - /* if there are any (buffered fd handling may generate them) - * then jump to processing them */ - if (_ecore_event_exist()) + // if there are any (buffered fd handling may generate them) + // then jump to processing them */ + if (efl_loop_message_exists(obj)) { - _ecore_main_select(0.0); - _efl_loop_timer_enable_new(); + _ecore_main_select(obj, pd, 0.0); + _efl_loop_timer_enable_new(obj, pd); goto process_all; } if (once_only) { - /* in once_only mode enter idle here instead and then return */ - _ecore_idle_enterer_call(_mainloop_singleton); + // in once_only mode enter idle here instead and then return + _ecore_idle_enterer_call(obj); _ecore_throttle(); - _efl_loop_timer_enable_new(); + _throttle_do(pd); + _efl_loop_timer_enable_new(obj, pd); goto done; } - _ecore_fps_marker_1(); - - /* start of the sleeping or looping section */ -start_loop: /*-*************************************************************/ - /* We could be looping here without exiting the function and we need to - process future and promise before the next waiting period. */ - /* destroy all optional futures */ - EINA_LIST_FREE(_pending_futures, f) - efl_del(f); - - /* and propagate all promise value */ - EINA_LIST_FREE(_pending_promises, p) - ecore_loop_promise_fulfill(p); - - /* any timers re-added as a result of these are allowed to go */ - _efl_loop_timer_enable_new(); - /* if we have been asked to quit the mainloop then exit at this point */ - if (do_quit) - { - _efl_loop_timer_enable_new(); + if (obj == ML_OBJ) _ecore_fps_marker_1(); + + // start of the sleeping or looping section +start_loop: //-************************************************************* + // We could be looping here without exiting the function and we need to + // process future and promise before the next waiting period. + // destroy all optional futures + EINA_LIST_FREE(pd->pending_futures, f) efl_del(f); + // and propagate all promise value + tmp = pd->pending_promises; + pd->pending_promises = NULL; + EINA_LIST_FREE(tmp, p) ecore_loop_promise_fulfill(p); + // any timers re-added as a result of these are allowed to go + _efl_loop_timer_enable_new(obj, pd); + // if we have been asked to quit the mainloop then exit at this point + if (pd->do_quit) + { + _efl_loop_timer_enable_new(obj, pd); goto done; } - if (!_ecore_event_exist()) + if (!efl_loop_message_exists(obj)) { - /* init flags */ - next_time = _efl_loop_timer_next_get(); - /* no idlers */ - if (!_ecore_idler_exist(_mainloop_singleton)) + // init flags + next_time = _efl_loop_timer_next_get(obj, pd); + // no idlers + if (!_ecore_idler_exist(obj)) { - /* sleep until timeout or forever (-1.0) waiting for on fds */ - _ecore_main_select(next_time); + // sleep until timeout or forever (-1.0) waiting for on fds + _ecore_main_select(obj, pd, next_time); } else { int action = LOOP_CONTINUE; - /* no timers - spin */ - if (next_time < 0) action = _ecore_main_loop_spin_no_timers(); + // no timers - spin + if (next_time < 0) action = _ecore_main_loop_spin_no_timers(obj, pd); /* timers - spin */ - else action = _ecore_main_loop_spin_timers(); + else action = _ecore_main_loop_spin_timers(obj, pd); if (action == SPIN_RESTART) goto start_loop; } } - _ecore_fps_marker_2(); + if (obj == ML_OBJ) _ecore_fps_marker_2(); - /* actually wake up and deal with input, events etc. */ -process_all: /*-*********************************************************/ + // actually wake up and deal with input, events etc. +process_all: //-********************************************************* - /* we came out of our "wait state" so idle has exited */ + // we came out of our "wait state" so idle has exited if (!once_only) { - _ecore_animator_run_reset(); - _ecore_idle_exiter_call(_mainloop_singleton); - } - /* call the fd handler per fd that became alive... */ - /* this should read or write any data to the monitored fd and then */ - /* post events onto the ecore event pipe if necessary */ - _ecore_main_fd_handlers_call(); - if (fd_handlers_with_buffer) _ecore_main_fd_handlers_buf_call(); - /* process signals into events .... */ - _ecore_signal_received_process(); - /* handle events ... */ - _ecore_event_call(); - _ecore_main_fd_handlers_cleanup(); + _ecore_animator_run_reset(); // XXX: + _ecore_idle_exiter_call(obj); + } + // call the fd handler per fd that became alive... + // this should read or write any data to the monitored fd and then + // post events onto the ecore event pipe if necessary + _ecore_main_fd_handlers_call(obj, pd); + if (pd->fd_handlers_with_buffer) _ecore_main_fd_handlers_buf_call(obj, pd); + // process signals into events .... + _ecore_signal_received_process(obj, pd); + // handle events ... + efl_loop_message_process(obj); // XXX: event queue per loop + _ecore_main_fd_handlers_cleanup(obj, pd); if (once_only) { - /* if in once_only mode handle idle exiting */ - _ecore_idle_enterer_call(_mainloop_singleton); + // if in once_only mode handle idle exiting + _ecore_idle_enterer_call(obj); _ecore_throttle(); + _throttle_do(pd); } -done: /*-*****************************************************************/ - /* Agressively flush animator */ +done: //-***************************************************************** + // Agressively flush animator _ecore_animator_flush(); if (!once_only) + eina_slstr_local_clear(); // Free all short lived strings + + if (obj == ML_OBJ) { - /* Free all short lived strings */ - eina_slstr_local_clear(); + in_main_loop--; + pd->in_loop = in_main_loop; } - in_main_loop--; } #endif @@ -2461,24 +2435,20 @@ done: /*-*****************************************************************/ #ifdef _WIN32 typedef struct { - DWORD objects_nbr; + DWORD objects_nbr; HANDLE *objects; - DWORD timeout; + DWORD timeout; } Ecore_Main_Win32_Thread_Data; static unsigned int __stdcall _ecore_main_win32_objects_wait_thread(void *data) { - Ecore_Main_Win32_Thread_Data *td; - DWORD result; - - td = (Ecore_Main_Win32_Thread_Data *)data; - result = MsgWaitForMultipleObjects(td->objects_nbr, - (const HANDLE *)td->objects, - FALSE, - td->timeout, - QS_ALLINPUT); - return result; + Ecore_Main_Win32_Thread_Data *td = (Ecore_Main_Win32_Thread_Data *)data; + return MsgWaitForMultipleObjects(td->objects_nbr, + (const HANDLE *)td->objects, + FALSE, + td->timeout, + QS_ALLINPUT); } static DWORD @@ -2488,26 +2458,19 @@ _ecore_main_win32_objects_wait(DWORD objects_nbr, { Ecore_Main_Win32_Thread_Data *threads_data; HANDLE *threads_handles; - DWORD threads_nbr; - DWORD threads_remain; - DWORD objects_idx; - DWORD result; - DWORD i; + DWORD threads_nbr threads_remain, objects_idx, result, i; if (objects_nbr < MAXIMUM_WAIT_OBJECTS) return MsgWaitForMultipleObjects(objects_nbr, objects, EINA_FALSE, timeout, QS_ALLINPUT); - /* - * too much objects, so we launch a bunch of threads to - * wait for, each one calls MsgWaitForMultipleObjects - */ + // too much objects, so we launch a bunch of threads to + // wait for, each one calls MsgWaitForMultipleObjects threads_nbr = objects_nbr / (MAXIMUM_WAIT_OBJECTS - 1); threads_remain = objects_nbr % (MAXIMUM_WAIT_OBJECTS - 1); - if (threads_remain > 0) - threads_nbr++; + if (threads_remain > 0) threads_nbr++; if (threads_nbr > MAXIMUM_WAIT_OBJECTS) { @@ -2522,7 +2485,8 @@ _ecore_main_win32_objects_wait(DWORD objects_nbr, return WAIT_FAILED; } - threads_data = (Ecore_Main_Win32_Thread_Data *)malloc(threads_nbr * sizeof(Ecore_Main_Win32_Thread_Data)); + threads_data = (Ecore_Main_Win32_Thread_Data *) + malloc(threads_nbr * sizeof(Ecore_Main_Win32_Thread_Data)); if (!threads_data) { ERR("Can not allocate memory for the waiting thread."); @@ -2546,12 +2510,9 @@ _ecore_main_win32_objects_wait(DWORD objects_nbr, objects_idx += (MAXIMUM_WAIT_OBJECTS - 1); } - threads_handles[i] = (HANDLE)_beginthreadex(NULL, - 0, - _ecore_main_win32_objects_wait_thread, - &threads_data[i], - 0, - NULL); + threads_handles[i] = (HANDLE)_beginthreadex + (NULL, 0, _ecore_main_win32_objects_wait_thread, + &threads_data[i], 0, NULL); if (!threads_handles[i]) { DWORD j; @@ -2567,22 +2528,21 @@ _ecore_main_win32_objects_wait(DWORD objects_nbr, result = WaitForMultipleObjects(threads_nbr, threads_handles, - FALSE, /* we wait until one thread is signaled */ + FALSE, // we wait until one thread signaled INFINITE); if (result < (WAIT_OBJECT_0 + threads_nbr)) { DWORD wait_res; - /* - * One of the thread callback has exited so we retrieve - * its exit status, that is the returned value of - * MsgWaitForMultipleObjects() - */ + // One of the thread callback has exited so we retrieve + // its exit status, that is the returned value of + // MsgWaitForMultipleObjects() if (GetExitCodeThread(threads_handles[result - WAIT_OBJECT_0], &wait_res)) { - WaitForMultipleObjects(threads_nbr, threads_handles, TRUE, INFINITE); + WaitForMultipleObjects(threads_nbr, threads_handles, + TRUE, INFINITE); for (i = 0; i < threads_nbr; i++) CloseHandle(threads_handles[i]); free(threads_data); @@ -2598,13 +2558,12 @@ _ecore_main_win32_objects_wait(DWORD objects_nbr, goto close_thread; } - close_thread: +close_thread: WaitForMultipleObjects(threads_nbr, threads_handles, TRUE, INFINITE); - for (i = 0; i < threads_nbr; i++) - CloseHandle(threads_handles[i]); - free_threads_data: + for (i = 0; i < threads_nbr; i++) CloseHandle(threads_handles[i]); +free_threads_data: free(threads_data); - free_threads_handles: +free_threads_handles: free(threads_handles); return WAIT_FAILED; @@ -2615,7 +2574,6 @@ _stdin_wait_thread(void *data EINA_UNUSED) { int c = getc(stdin); ungetc(c, stdin); - return 0; } @@ -2626,39 +2584,41 @@ _ecore_main_win32_select(int nfds EINA_UNUSED, fd_set *exceptfds, struct timeval *tv) { + Eo *obj = ML_OBJ; + Efl_Loop_Data *pd = ML_DAT; HANDLE *objects; - static HANDLE stdin_wait_thread = INVALID_HANDLE_VALUE; - Eina_Bool stdin_thread_done = EINA_FALSE; - HANDLE stdin_handle; int *sockets; Ecore_Fd_Handler *fdh; Ecore_Win32_Handler *wh; + static HANDLE stdin_wait_thread = INVALID_HANDLE_VALUE; + HANDLE stdin_handle; + DWORD result, timeout; + MSG msg; unsigned int fds_nbr = 0; unsigned int objects_nbr = 0; unsigned int events_nbr = 0; - DWORD result; - DWORD timeout; - MSG msg; unsigned int i; int res; + Eina_Bool stdin_thread_done = EINA_FALSE; - fds_nbr = eina_inlist_count(EINA_INLIST_GET(fd_handlers)); + fds_nbr = eina_inlist_count(EINA_INLIST_GET(pd->fd_handlers)); sockets = (int *)malloc(fds_nbr * sizeof(int)); - if (!sockets) - return -1; + if (!sockets) return -1; - objects = (HANDLE)malloc((fds_nbr + eina_inlist_count(EINA_INLIST_GET(win32_handlers))) * sizeof(HANDLE)); + objects = (HANDLE)malloc((fds_nbr + + eina_inlist_count + (EINA_INLIST_GET(pd->win32_handlers))) + * sizeof(HANDLE)); if (!objects) { free(sockets); return -1; } - /* Create an event object per socket */ - EINA_INLIST_FOREACH(fd_handlers, fdh) + // Create an event object per socket + EINA_INLIST_FOREACH(pd->fd_handlers, fdh) { - if (fdh->delete_me) - continue; + if (fdh->delete_me) continue; WSAEVENT event; long network_event; @@ -2691,11 +2651,10 @@ _ecore_main_win32_select(int nfds EINA_UNUSED, } } stdin_handle = GetStdHandle(STD_INPUT_HANDLE); - /* store the HANDLEs in the objects to wait for */ - EINA_INLIST_FOREACH(win32_handlers, wh) + // store the HANDLEs in the objects to wait for + EINA_INLIST_FOREACH(pd->win32_handlers, wh) { - if (wh->delete_me) - continue; + if (wh->delete_me) continue; if (wh->h == stdin_handle) { @@ -2708,26 +2667,21 @@ _ecore_main_win32_select(int nfds EINA_UNUSED, NULL); objects[objects_nbr] = stdin_wait_thread; } - else - { - objects[objects_nbr] = wh->h; - } + else objects[objects_nbr] = wh->h; objects_nbr++; } - /* Empty the queue before waiting */ + // Empty the queue before waiting while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } - /* Wait for any message sent or posted to this queue */ - /* or for one of the passed handles be set to signaled. */ - if (!tv) - timeout = INFINITE; - else - timeout = (DWORD)((tv->tv_sec * 1000.0) + (tv->tv_usec / 1000.0)); + // Wait for any message sent or posted to this queue + // or for one of the passed handles be set to signaled. + if (!tv) timeout = INFINITE; + else timeout = (DWORD)((tv->tv_sec * 1000.0) + (tv->tv_usec / 1000.0)); if (timeout == 0) { @@ -2738,15 +2692,10 @@ _ecore_main_win32_select(int nfds EINA_UNUSED, result = _ecore_main_win32_objects_wait(objects_nbr, (const HANDLE *)objects, timeout); - - if (readfds) - FD_ZERO(readfds); - if (writefds) - FD_ZERO(writefds); - if (exceptfds) - FD_ZERO(exceptfds); - - /* The result tells us the type of event we have. */ + if (readfds) FD_ZERO(readfds); + if (writefds) FD_ZERO(writefds); + if (exceptfds) FD_ZERO(exceptfds); + // The result tells us the type of event we have. if (result == WAIT_FAILED) { WRN("%s", evil_last_error_get()); @@ -2764,7 +2713,6 @@ _ecore_main_win32_select(int nfds EINA_UNUSED, TranslateMessage(&msg); DispatchMessage(&msg); } - res = 0; } else if (result < WAIT_OBJECT_0 + events_nbr) @@ -2772,39 +2720,37 @@ _ecore_main_win32_select(int nfds EINA_UNUSED, WSANETWORKEVENTS network_event; WSAEnumNetworkEvents(sockets[result], objects[result], &network_event); - - if ((network_event.lNetworkEvents & (FD_READ | FD_CONNECT | FD_ACCEPT)) && readfds) + if ((network_event.lNetworkEvents & + (FD_READ | FD_CONNECT | FD_ACCEPT)) && readfds) FD_SET(sockets[result], readfds); - if ((network_event.lNetworkEvents & (FD_WRITE | FD_CLOSE)) && writefds) + if ((network_event.lNetworkEvents & + (FD_WRITE | FD_CLOSE)) && writefds) FD_SET(sockets[result], writefds); if ((network_event.lNetworkEvents & FD_OOB) && exceptfds) FD_SET(sockets[result], exceptfds); - res = 1; } else if ((result >= (WAIT_OBJECT_0 + events_nbr)) && (result < (WAIT_OBJECT_0 + objects_nbr))) { - if (!win32_handler_current) - { - /* regular main loop, start from head */ - win32_handler_current = win32_handlers; - } + if (!pd->win32_handler_current) + // regular main loop, start from head + pd->win32_handler_current = pd->win32_handlers; else - { - /* recursive main loop, continue from where we were */ - win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next; - } + // recursive main loop, continue from where we were + pd->win32_handler_current = (Ecore_Win32_Handler *) + EINA_INLIST_GET(pd->win32_handler_current)->next; if (objects[result - WAIT_OBJECT_0] == stdin_wait_thread) stdin_thread_done = EINA_TRUE; - while (win32_handler_current) + while (pd->win32_handler_current) { - wh = win32_handler_current; + wh = pd->win32_handler_current; - if (objects[result - WAIT_OBJECT_0] == wh->h || - (objects[result - WAIT_OBJECT_0] == stdin_wait_thread && wh->h == stdin_handle)) + if ((objects[result - WAIT_OBJECT_0] == wh->h) || + ((objects[result - WAIT_OBJECT_0] == stdin_wait_thread) && + (wh->h == stdin_handle))) { if (!wh->delete_me) { @@ -2812,13 +2758,16 @@ _ecore_main_win32_select(int nfds EINA_UNUSED, if (!wh->func(wh->data, wh)) { wh->delete_me = EINA_TRUE; - win32_handlers_to_delete = eina_list_append(win32_handlers_to_delete, wh); + pd->win32_handlers_to_delete = eina_list_append + (pd->win32_handlers_to_delete, wh); } wh->references--; } } - if (win32_handler_current) /* may have changed in recursive main loops */ - win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next; + if (pd->win32_handler_current) + // may have changed in recursive main loops + pd->win32_handler_current = (Ecore_Win32_Handler *) + EINA_INLIST_GET(pd->win32_handler_current)->next; } res = 1; } @@ -2828,508 +2777,14 @@ _ecore_main_win32_select(int nfds EINA_UNUSED, res = -1; } -err : - /* Remove event objects again */ +err: + // Remove event objects again for (i = 0; i < events_nbr; i++) WSACloseEvent(objects[i]); - if (stdin_thread_done) - stdin_wait_thread = INVALID_HANDLE_VALUE; + if (stdin_thread_done) stdin_wait_thread = INVALID_HANDLE_VALUE; free(objects); free(sockets); return res; } - #endif - -Eo *_mainloop_singleton = NULL; - -EOLIAN static Efl_Loop * -_efl_loop_main_get(Efl_Class *klass EINA_UNUSED, void *_pd EINA_UNUSED) -{ - if (!_mainloop_singleton) - { - _mainloop_singleton = efl_add(EFL_LOOP_CLASS, NULL); - } - - return _mainloop_singleton; -} - -EAPI Eo * -ecore_main_loop_get(void) -{ - return efl_loop_main_get(EFL_LOOP_CLASS); -} - -EOLIAN static void -_efl_loop_iterate(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) -{ - ecore_main_loop_iterate(); -} - -EOLIAN static int _efl_loop_iterate_may_block(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED, int may_block) -{ - return ecore_main_loop_iterate_may_block(may_block); -} - -// FIXME: This should return an Eina_Value, but that doesn't work at the moment -EOLIAN static Eina_Value * -_efl_loop_begin(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) -{ - ecore_main_loop_begin(); - return &_ecore_exit_code; -} - -EOLIAN static void -_efl_loop_quit(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED, Eina_Value exit_code) -{ - ecore_main_loop_quit(); - _ecore_exit_code = exit_code; -} - -EAPI void -efl_exit(int exit_code) -{ - Eina_Value v = EINA_VALUE_EMPTY; - - eina_value_setup(&v, EINA_VALUE_TYPE_INT); - eina_value_set(&v, &exit_code); - efl_loop_quit(ecore_main_loop_get(), v); -} - -EOLIAN static Efl_Object * -_efl_loop_efl_object_provider_find(Eo *obj, Efl_Loop_Data *pd, const Efl_Object *klass) -{ - Efl_Object *r; - - if (klass == EFL_LOOP_CLASS) return obj; - - r = eina_hash_find(pd->providers, &klass); - if (r) return r; - - return efl_provider_find(efl_super(obj, EFL_LOOP_CLASS), klass); -} - -EAPI int -efl_loop_exit_code_process(Eina_Value *value) -{ - const Eina_Value_Type *t = eina_value_type_get(value); - int r = 0; - - if (t == EINA_VALUE_TYPE_UCHAR || - t == EINA_VALUE_TYPE_USHORT || - t == EINA_VALUE_TYPE_UINT || - t == EINA_VALUE_TYPE_ULONG || - t == EINA_VALUE_TYPE_UINT64 || - t == EINA_VALUE_TYPE_CHAR || - t == EINA_VALUE_TYPE_SHORT || - t == EINA_VALUE_TYPE_INT || - t == EINA_VALUE_TYPE_LONG || - t == EINA_VALUE_TYPE_INT64 || - t == EINA_VALUE_TYPE_FLOAT || - t == EINA_VALUE_TYPE_DOUBLE) - { - Eina_Value v = EINA_VALUE_EMPTY; - - eina_value_setup(&v, EINA_VALUE_TYPE_INT); - if (!eina_value_convert(&v, value)) - r = -1; - else - eina_value_get(&v, &v); - } - else - { - FILE *out = stdout; - char *msg; - - msg = eina_value_to_string(value); - - if (t == EINA_VALUE_TYPE_ERROR) - { - r = -1; - out = stderr; - } - - fprintf(out, "%s\n", msg); - } - - return r; -} - -static void -_poll_trigger(void *data, const Efl_Event *event) -{ - Eo *parent = efl_parent_get(event->object); - - efl_event_callback_call(parent, data, NULL); -} - -static void -_check_event_catcher_add(void *data, const Efl_Event *event) -{ - const Efl_Callback_Array_Item *array = event->info; - Efl_Loop_Data *pd = data; - int i; - - for (i = 0; array[i].desc != NULL; i++) - { - if (array[i].desc == EFL_LOOP_EVENT_IDLE) - { - ++pd->idlers; - } - // XXX: all the below are kind of bad. ecore_pollers were special. - // they all woke up at the SAME time based on interval, (all pollers - // of interval 1 woke up together, those with 2 woke up when 1 and - // 2 woke up, 4 woke up together along with 1 and 2 etc. - // the below means they will just go off whenever but at a pre - // defined interval - 1/60th, 6 and 66 seconds. not really great - // pollers probably should be less frequent that 1/60th even on poll - // high, medium probably down to 1-2 sec and low - yes maybe 30 or 60 - // sec... still - not timed to wake up together. :( - else if (array[i].desc == EFL_LOOP_EVENT_POLL_HIGH) - { - if (!pd->poll_high) - { - // Would be better to have it in sync with normal wake up - // of the main loop for better energy efficiency, I guess. - pd->poll_high = efl_add(EFL_LOOP_TIMER_CLASS, event->object, - efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_HIGH), - efl_loop_timer_interval_set(efl_added, 1.0/60.0)); - } - ++pd->pollers.high; - } - else if (array[i].desc == EFL_LOOP_EVENT_POLL_MEDIUM) - { - if (!pd->poll_medium) - { - pd->poll_medium = efl_add(EFL_LOOP_TIMER_CLASS, event->object, - efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_MEDIUM), - efl_loop_timer_interval_set(efl_added, 6)); - } - ++pd->pollers.medium; - } - else if (array[i].desc == EFL_LOOP_EVENT_POLL_LOW) - { - if (!pd->poll_low) - { - pd->poll_low = efl_add(EFL_LOOP_TIMER_CLASS, event->object, - efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_LOW), - efl_loop_timer_interval_set(efl_added, 66)); - } - ++pd->pollers.low; - } - } -} - -static void -_check_event_catcher_del(void *data, const Efl_Event *event) -{ - const Efl_Callback_Array_Item *array = event->info; - Efl_Loop_Data *pd = data; - int i; - - for (i = 0; array[i].desc != NULL; i++) - { - if (array[i].desc == EFL_LOOP_EVENT_IDLE) - { - --pd->idlers; - } - else if (array[i].desc == EFL_LOOP_EVENT_POLL_HIGH) - { - --pd->pollers.high; - if (!pd->pollers.high) - { - efl_del(pd->poll_high); - pd->poll_high = NULL; - } - } - else if (array[i].desc == EFL_LOOP_EVENT_POLL_MEDIUM) - { - --pd->pollers.medium; - if (!pd->pollers.medium) - { - efl_del(pd->poll_medium); - pd->poll_medium = NULL; - } - } - else if (array[i].desc == EFL_LOOP_EVENT_POLL_LOW) - { - --pd->pollers.low; - if (!pd->pollers.low) - { - efl_del(pd->poll_low); - pd->poll_low = NULL; - } - } - } -} - -EFL_CALLBACKS_ARRAY_DEFINE(event_catcher_watch, - { EFL_EVENT_CALLBACK_ADD, _check_event_catcher_add }, - { EFL_EVENT_CALLBACK_DEL, _check_event_catcher_del }); - -EOLIAN static Efl_Object * -_efl_loop_efl_object_constructor(Eo *obj, Efl_Loop_Data *pd) -{ - obj = efl_constructor(efl_super(obj, EFL_LOOP_CLASS)); - if (!obj) return NULL; - - efl_event_callback_array_add(obj, event_catcher_watch(), pd); - - pd->providers = eina_hash_pointer_new(EINA_FREE_CB(efl_unref)); - - return obj; -} - -EOLIAN static void -_efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd) -{ - eina_hash_free(pd->providers); - - efl_del(pd->poll_low); - efl_del(pd->poll_medium); - efl_del(pd->poll_high); - - efl_destructor(efl_super(obj, EFL_LOOP_CLASS)); -} - -static void -_efl_loop_arguments_cleanup(Eina_Array *arga) -{ - Eina_Stringshare *s; - - while ((s = eina_array_pop(arga))) - eina_stringshare_del(s); - eina_array_free(arga); -} - -static Eina_Value -_efl_loop_arguments_send(void *data, const Eina_Value v, - const Eina_Future *dead EINA_UNUSED) -{ - static Eina_Bool initialization = EINA_TRUE; - Efl_Loop_Arguments arge; - Eina_Array *arga = data; - - if (v.type == EINA_VALUE_TYPE_ERROR) - goto on_error; - - arge.argv = arga; - arge.initialization = initialization; - initialization = EINA_FALSE; - - efl_event_callback_call(ecore_main_loop_get(), EFL_LOOP_EVENT_ARGUMENTS, &arge); - - on_error: - _efl_loop_arguments_cleanup(arga); - - return v; -} - -// It doesn't make sense to send those argument to any other mainloop -// As it also doesn't make sense to allow anyone to override this, so -// should be internal for sure, not even protected. -EAPI void -ecore_loop_arguments_send(int argc, const char **argv) -{ - Eina_Future *job; - Eina_Array *arga; - int i = 0; - - arga = eina_array_new(argc); - for (i = 0; i < argc; i++) - eina_array_push(arga, eina_stringshare_add(argv[i])); - - job = eina_future_then(efl_loop_job(ecore_main_loop_get()), - _efl_loop_arguments_send, arga); - efl_future_Eina_FutureXXX_then(ecore_main_loop_get(), job); -} - -// Only one main loop handle for now -void -ecore_loop_future_register(Efl_Loop *l EINA_UNUSED, Efl_Future *f) -{ - _pending_futures = eina_list_append(_pending_futures, f); -} - -void -ecore_loop_future_unregister(Efl_Loop *l EINA_UNUSED, Efl_Future *f) -{ - _pending_futures = eina_list_remove(_pending_futures, f); -} - -void -ecore_loop_promise_register(Efl_Loop *l EINA_UNUSED, Efl_Promise *p) -{ - _pending_promises = eina_list_append(_pending_promises, p); -} - -void -ecore_loop_promise_unregister(Efl_Loop *l EINA_UNUSED, Efl_Promise *p) -{ - _pending_promises = eina_list_remove(_pending_promises, p); -} - -static Eina_Future * -_efl_loop_job(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED) -{ - // NOTE: Eolian should do efl_future_then() to bind future to object. - return efl_future_Eina_FutureXXX_then(obj, - eina_future_resolved(efl_loop_future_scheduler_get(obj), - EINA_VALUE_EMPTY)); -} - -static void -_efl_loop_idle_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED) -{ - Efl_Loop_Promise_Simple_Data *d = data; - ecore_idler_del(d->idler); - efl_loop_promise_simple_data_mp_free(d); -} - -static Eina_Bool -_efl_loop_idle_done(void *data) -{ - Efl_Loop_Promise_Simple_Data *d = data; - eina_promise_resolve(d->promise, EINA_VALUE_EMPTY); - efl_loop_promise_simple_data_mp_free(d); - return EINA_FALSE; -} - -static Eina_Future * -_efl_loop_idle(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED) -{ - Efl_Loop_Promise_Simple_Data *d; - Eina_Promise *p; - - d = efl_loop_promise_simple_data_calloc(1); - EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL); - - d->idler = ecore_idler_add(_efl_loop_idle_done, d); - EINA_SAFETY_ON_NULL_GOTO(d->idler, idler_error); - - p = eina_promise_new(efl_loop_future_scheduler_get(obj), - _efl_loop_idle_cancel, d); - // d is dead if p is NULL - EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL); - d->promise = p; - - // NOTE: Eolian should do efl_future_then() to bind future to object. - return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p)); - - idler_error: - efl_loop_promise_simple_data_mp_free(d); - return NULL; -} - -static void -_efl_loop_timeout_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED) -{ - Efl_Loop_Promise_Simple_Data *d = data; - ecore_timer_del(d->timer); - efl_loop_promise_simple_data_mp_free(d); -} - -static Eina_Bool -_efl_loop_timeout_done(void *data) -{ - Efl_Loop_Promise_Simple_Data *d = data; - eina_promise_resolve(d->promise, EINA_VALUE_EMPTY); - efl_loop_promise_simple_data_mp_free(d); - return EINA_FALSE; -} - -static Eina_Future * -_efl_loop_timeout(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, double time) -{ - Efl_Loop_Promise_Simple_Data *d; - Eina_Promise *p; - - d = efl_loop_promise_simple_data_calloc(1); - EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL); - - d->timer = ecore_timer_add(time, _efl_loop_timeout_done, d); - EINA_SAFETY_ON_NULL_GOTO(d->timer, timer_error); - - p = eina_promise_new(efl_loop_future_scheduler_get(obj), - _efl_loop_timeout_cancel, d); - // d is dead if p is NULL - EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL); - d->promise = p; - - // NOTE: Eolian should do efl_future_then() to bind future to object. - return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p)); - - timer_error: - efl_loop_promise_simple_data_mp_free(d); - return NULL; -} - -static Eina_Bool -_efl_loop_register(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, const Efl_Class *klass, const Efl_Object *provider) -{ - // The passed object does not provide that said class. - if (!efl_isa(provider, klass)) return EINA_FALSE; - - // Note: I would prefer to use efl_xref here, but I can't figure a nice way to - // call efl_xunref on hash destruction. - return eina_hash_add(pd->providers, &klass, efl_ref(provider)); -} - -static Eina_Bool -_efl_loop_unregister(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, const Efl_Class *klass, const Efl_Object *provider) -{ - return eina_hash_del(pd->providers, &klass, provider); -} - -Efl_Version _app_efl_version = { 0, 0, 0, 0, NULL, NULL }; - -EWAPI void -efl_build_version_set(int vmaj, int vmin, int vmic, int revision, - const char *flavor, const char *build_id) -{ - // note: EFL has not been initialized yet at this point (ie. no eina call) - _app_efl_version.major = vmaj; - _app_efl_version.minor = vmin; - _app_efl_version.micro = vmic; - _app_efl_version.revision = revision; - free((char *) _app_efl_version.flavor); - free((char *) _app_efl_version.build_id); - _app_efl_version.flavor = flavor ? strdup(flavor) : NULL; - _app_efl_version.build_id = build_id ? strdup(build_id) : NULL; -} - -EOLIAN static const Efl_Version * -_efl_loop_app_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) -{ - return &_app_efl_version; -} - -EOLIAN static const Efl_Version * -_efl_loop_efl_version_get(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED) -{ - /* vanilla EFL: flavor = NULL */ - static const Efl_Version version = { - .major = VMAJ, - .minor = VMIN, - .micro = VMIC, - .revision = VREV, - .build_id = EFL_BUILD_ID, - .flavor = NULL - }; - - return &version; -} - -EAPI Eina_Future_Scheduler * -efl_loop_future_scheduler_get(Eo *obj) -{ - if (!obj) return NULL; - - if (efl_isa(obj, EFL_LOOP_CLASS)) - return _ecore_event_future_scheduler_get(); - - return efl_loop_future_scheduler_get(efl_loop_get(obj)); -} - -#include "efl_loop.eo.c" |