2008-06-11 13:36:35 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
2008-01-25 21:40:53 -08:00
|
|
|
|
2017-01-10 22:34:15 -08:00
|
|
|
#define EINA_SLSTR_INTERNAL
|
|
|
|
|
2008-05-25 22:16:34 -07:00
|
|
|
#ifdef _WIN32
|
2010-04-05 01:26:48 -07:00
|
|
|
# ifndef USER_TIMER_MINIMUM
|
|
|
|
# define USER_TIMER_MINIMUM 0x0a
|
|
|
|
# endif
|
2008-01-25 21:40:53 -08:00
|
|
|
#endif
|
2004-10-20 10:51:29 -07:00
|
|
|
|
2009-01-31 10:33:39 -08:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
2016-06-13 12:44:10 -07:00
|
|
|
#include <string.h>
|
2013-01-10 12:25:26 -08:00
|
|
|
#include <unistd.h>
|
2006-01-01 12:29:34 -08:00
|
|
|
#include <math.h>
|
2003-09-23 01:09:32 -07:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <errno.h>
|
2009-04-10 05:48:25 -07:00
|
|
|
#include <fcntl.h>
|
2013-01-10 12:25:57 -08:00
|
|
|
#include <sys/time.h>
|
2012-11-18 22:26:48 -08:00
|
|
|
|
2013-03-10 04:53:58 -07:00
|
|
|
#ifdef HAVE_SYSTEMD
|
|
|
|
# include <systemd/sd-daemon.h>
|
|
|
|
#endif
|
|
|
|
|
2016-06-13 12:44:10 -07:00
|
|
|
#ifdef HAVE_IEEEFP_H
|
2017-11-08 22:59:04 -08:00
|
|
|
# include <ieeefp.h> // for Solaris
|
2016-06-13 12:44:10 -07:00
|
|
|
#endif
|
|
|
|
|
2011-04-11 12:58:56 -07:00
|
|
|
#ifdef HAVE_ISFINITE
|
2011-10-20 22:40:39 -07:00
|
|
|
# define ECORE_FINITE(t) isfinite(t)
|
2011-04-11 12:58:56 -07:00
|
|
|
#else
|
2018-01-02 21:23:10 -08:00
|
|
|
# define ECORE_FINITE(t) finite(t)
|
2011-04-11 12:58:56 -07:00
|
|
|
#endif
|
|
|
|
|
2011-07-04 21:08:01 -07:00
|
|
|
//#define FIX_HZ 1
|
2006-01-06 22:48:56 -08:00
|
|
|
|
2004-06-09 03:35:01 -07:00
|
|
|
#ifdef FIX_HZ
|
2018-01-02 21:23:10 -08:00
|
|
|
# include <sys/param.h>
|
2007-09-30 08:24:51 -07:00
|
|
|
# ifndef HZ
|
|
|
|
# define HZ 100
|
|
|
|
# endif
|
2004-06-09 03:35:01 -07:00
|
|
|
#endif
|
|
|
|
|
2017-09-22 03:06:10 -07:00
|
|
|
#ifdef _WIN32
|
2009-04-11 06:46:09 -07:00
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
|
|
|
|
2011-01-07 07:56:54 -08:00
|
|
|
#include "Ecore.h"
|
|
|
|
#include "ecore_private.h"
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
#include "ecore_main_common.h"
|
2011-07-06 03:54:11 -07:00
|
|
|
|
2017-12-18 16:17:04 -08:00
|
|
|
#include "eina_internal.h"
|
|
|
|
|
2010-08-14 04:19:03 -07:00
|
|
|
#ifdef USE_G_MAIN_LOOP
|
2010-10-07 00:23:26 -07:00
|
|
|
# include <glib.h>
|
2010-08-14 04:19:03 -07:00
|
|
|
#endif
|
|
|
|
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
# 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
|
2014-09-01 11:08:49 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// XXX: FIXME: use eina_module
|
|
|
|
# if defined(HAVE_DLOPEN) && !defined(_WIN32)
|
|
|
|
# include <dlfcn.h>
|
|
|
|
# endif
|
2014-09-01 11:08:49 -07:00
|
|
|
|
|
|
|
static uv_prepare_t _ecore_main_uv_prepare;
|
|
|
|
static uv_check_t _ecore_main_uv_check;
|
|
|
|
static uv_timer_t _ecore_main_uv_handle_timers;
|
|
|
|
static Eina_Bool _ecore_main_uv_idling;
|
|
|
|
|
|
|
|
static int (*_dl_uv_loop_alive)(uv_loop_t*) = 0;
|
|
|
|
static int (*_dl_uv_run)(uv_loop_t*, uv_run_mode mode) = 0;
|
|
|
|
static int (*_dl_uv_stop)(uv_loop_t*) = 0;
|
|
|
|
static uv_loop_t* (*_dl_uv_default_loop)() = 0;
|
|
|
|
static int (*_dl_uv_poll_init_socket)(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t fd) = 0;
|
|
|
|
static int (*_dl_uv_poll_init)(uv_loop_t* loop, uv_poll_t* handle, int fd) = 0;
|
|
|
|
static int (*_dl_uv_poll_start)(uv_poll_t* handle, int events, uv_poll_cb cb) = 0;
|
|
|
|
static int (*_dl_uv_poll_stop)(uv_poll_t* handle) = 0;
|
|
|
|
static int (*_dl_uv_timer_init)(uv_loop_t*, uv_timer_t* handle);
|
|
|
|
static int (*_dl_uv_timer_start)(uv_timer_t* handle,
|
|
|
|
uv_timer_cb cb,
|
|
|
|
uint64_t timeout,
|
|
|
|
uint64_t repeat);
|
|
|
|
static int (*_dl_uv_timer_stop)(uv_timer_t* handle);
|
|
|
|
static int (*_dl_uv_prepare_init)(uv_loop_t*, uv_prepare_t* prepare);
|
|
|
|
static int (*_dl_uv_prepare_start)(uv_prepare_t* prepare, uv_prepare_cb cb);
|
|
|
|
static int (*_dl_uv_prepare_stop)(uv_prepare_t* prepare);
|
|
|
|
static int (*_dl_uv_check_init)(uv_loop_t*, uv_check_t* prepare);
|
|
|
|
static int (*_dl_uv_check_start)(uv_check_t* prepare, uv_check_cb cb);
|
|
|
|
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
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
#define NS_PER_SEC (1000000000.0)
|
2011-07-06 03:54:11 -07:00
|
|
|
|
2011-12-11 00:29:35 -08:00
|
|
|
struct _Ecore_Fd_Handler
|
|
|
|
{
|
|
|
|
EINA_INLIST;
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2011-12-11 00:29:35 -08:00
|
|
|
#if defined(USE_G_MAIN_LOOP)
|
2017-11-08 22:59:04 -08:00
|
|
|
GPollFD gfd;
|
2011-12-11 00:29:35 -08:00
|
|
|
#endif
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
uv_poll_t uv_handle;
|
2014-09-01 11:08:49 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
Eina_Bool read_active : 1;
|
|
|
|
Eina_Bool write_active : 1;
|
|
|
|
Eina_Bool error_active : 1;
|
|
|
|
Eina_Bool delete_me : 1;
|
|
|
|
Eina_Bool file : 1;
|
2018-02-20 22:45:55 -08:00
|
|
|
Eina_Bool legacy : 1;
|
2011-12-11 00:29:35 -08:00
|
|
|
};
|
|
|
|
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Fd_Handler);
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
struct _Ecore_Win32_Handler
|
|
|
|
{
|
|
|
|
EINA_INLIST;
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2011-12-11 00:29:35 -08:00
|
|
|
};
|
|
|
|
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Win32_Handler);
|
|
|
|
#endif
|
|
|
|
|
2014-09-01 11:08:49 -07:00
|
|
|
#if !defined(USE_G_MAIN_LOOP) && !defined(HAVE_LIBUV)
|
2017-11-08 22:59:04 -08:00
|
|
|
static int _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout);
|
2011-06-01 23:08:59 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
2009-11-23 15:09:48 -08:00
|
|
|
#ifndef _WIN32
|
2011-06-01 23:08:59 -07:00
|
|
|
# ifndef USE_G_MAIN_LOOP
|
2017-11-08 22:59:04 -08:00
|
|
|
static void _ecore_main_fd_handlers_bads_rem(Eo *obj, Efl_Loop_Data *pd);
|
2011-06-01 23:08:59 -07:00
|
|
|
# endif
|
2009-11-23 15:09:48 -08:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
2010-08-14 04:19:03 -07:00
|
|
|
#ifndef USE_G_MAIN_LOOP
|
2017-11-08 22:59:04 -08:00
|
|
|
static void _ecore_main_loop_iterate_internal(Eo *obj, Efl_Loop_Data *pd, int once_only);
|
2010-08-14 04:19:03 -07:00
|
|
|
#endif
|
2003-09-23 01:09:32 -07:00
|
|
|
|
2009-06-23 23:14:07 -07:00
|
|
|
#ifdef _WIN32
|
2011-10-20 22:40:39 -07:00
|
|
|
static int _ecore_main_win32_select(int nfds,
|
|
|
|
fd_set *readfds,
|
|
|
|
fd_set *writefds,
|
|
|
|
fd_set *exceptfds,
|
|
|
|
struct timeval *timeout);
|
2017-11-08 22:59:04 -08:00
|
|
|
static void _ecore_main_win32_handlers_cleanup(Eo *obj, Efl_Loop_Data *pd);
|
2009-10-25 00:07:48 -07:00
|
|
|
#endif
|
2009-06-23 23:14:07 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
static void _ecore_main_loop_setup(Eo *obj, Efl_Loop_Data *pd);
|
|
|
|
static void _ecore_main_loop_clear(Eo *obj, Efl_Loop_Data *pd);
|
2003-09-23 01:09:32 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// for legacy mainloop only and not other loops
|
|
|
|
int in_main_loop = 0;
|
2011-06-01 23:08:59 -07:00
|
|
|
#ifndef USE_G_MAIN_LOOP
|
2011-10-20 22:40:39 -07:00
|
|
|
static double t1 = 0.0;
|
|
|
|
static double t2 = 0.0;
|
2011-06-01 23:08:59 -07:00
|
|
|
#endif
|
2004-03-16 21:14:13 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
#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;
|
2017-04-21 20:20:06 -07:00
|
|
|
#endif
|
2010-07-27 23:08:35 -07:00
|
|
|
|
2010-08-14 04:19:03 -07:00
|
|
|
#ifdef USE_G_MAIN_LOOP
|
2017-11-08 22:59:04 -08:00
|
|
|
static GPollFD ecore_epoll_fd;
|
|
|
|
static GPollFD ecore_timer_fd;
|
|
|
|
static GSource *ecore_glib_source;
|
|
|
|
static guint ecore_glib_source_id;
|
2011-10-20 22:40:39 -07:00
|
|
|
static GMainLoop *ecore_main_loop;
|
2017-11-08 22:59:04 -08:00
|
|
|
static gboolean ecore_idling;
|
|
|
|
static gboolean _ecore_glib_idle_enterer_called;
|
|
|
|
static gboolean ecore_fds_ready;
|
2010-07-27 23:08:35 -07:00
|
|
|
#endif
|
|
|
|
|
2017-02-10 09:58:24 -08:00
|
|
|
#ifdef EFL_EXTRA_SANITY_CHECKS
|
2011-07-06 03:54:30 -07:00
|
|
|
static inline void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_fd_valid(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
|
2010-12-31 19:07:58 -08:00
|
|
|
{
|
2018-02-20 22:38:30 -08:00
|
|
|
# ifdef HAVE_SYS_EPOLL_H
|
2017-11-08 22:59:04 -08:00
|
|
|
if ((pd->epoll_fd >= 0) &&
|
|
|
|
(fcntl(pd->epoll_fd, F_GETFD) < 0))
|
2010-12-31 19:07:58 -08:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
ERR("arghhh you caught me! report a backtrace to edevel!");
|
|
|
|
# ifdef HAVE_PAUSE
|
|
|
|
pause();
|
|
|
|
# else
|
|
|
|
sleep(60);
|
|
|
|
# endif
|
2010-12-31 19:07:58 -08:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
# endif
|
2010-12-31 19:07:58 -08:00
|
|
|
}
|
2017-02-10 09:58:24 -08:00
|
|
|
#endif
|
2010-12-31 19:07:58 -08:00
|
|
|
|
2011-01-28 21:34:00 -08:00
|
|
|
static inline void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_try_add_to_call_list(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, Ecore_Fd_Handler *fdh)
|
2011-01-28 21:34:00 -08:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// check if this fdh is already in the list
|
2012-08-12 19:55:41 -07:00
|
|
|
if (fdh->next_ready)
|
2014-09-01 11:08:49 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
DBG("next_ready");
|
|
|
|
return;
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
2012-08-12 19:55:41 -07:00
|
|
|
if (fdh->read_active || fdh->write_active || fdh->error_active)
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2012-08-12 19:55:41 -07:00
|
|
|
}
|
2011-01-28 21:34:00 -08:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-02-20 22:38:30 -08:00
|
|
|
#ifdef HAVE_SYS_EPOLL_H
|
2010-10-20 07:15:56 -07:00
|
|
|
static inline int
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_get_epoll_fd(Eo *obj, Efl_Loop_Data *pd)
|
2010-10-20 07:15:56 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2010-10-20 07:15:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
2011-10-20 22:40:39 -07:00
|
|
|
_ecore_epoll_add(int efd,
|
|
|
|
int fd,
|
|
|
|
int events,
|
|
|
|
void *ptr)
|
2010-10-20 07:15:56 -07:00
|
|
|
{
|
|
|
|
struct epoll_event ev;
|
|
|
|
|
|
|
|
memset(&ev, 0, sizeof (ev));
|
|
|
|
ev.events = events;
|
|
|
|
ev.data.ptr = ptr;
|
2013-03-16 07:08:19 -07:00
|
|
|
DBG("adding poll on %d %08x", fd, events);
|
2010-10-20 07:15:56 -07:00
|
|
|
return epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev);
|
|
|
|
}
|
|
|
|
|
2010-10-07 00:23:26 -07:00
|
|
|
static inline int
|
|
|
|
_ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh)
|
2010-07-27 23:08:35 -07:00
|
|
|
{
|
|
|
|
int events = 0;
|
2018-02-20 22:38:30 -08:00
|
|
|
if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN | EPOLLHUP;
|
|
|
|
if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT | EPOLLHUP;
|
|
|
|
if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR | EPOLLPRI | EPOLLHUP;
|
2010-07-27 23:08:35 -07:00
|
|
|
return events;
|
|
|
|
}
|
2017-04-21 20:20:06 -07:00
|
|
|
#endif
|
2010-07-27 23:08:35 -07:00
|
|
|
|
2010-10-07 00:23:26 -07:00
|
|
|
#ifdef USE_G_MAIN_LOOP
|
|
|
|
static inline int
|
|
|
|
_gfd_events_from_fdh(Ecore_Fd_Handler *fdh)
|
|
|
|
{
|
|
|
|
int events = 0;
|
2018-02-20 22:38:30 -08:00
|
|
|
if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN | G_IO_HUP;
|
|
|
|
if (fdh->flags & ECORE_FD_WRITE) events |= G_IO_OUT | G_IO_HUP;
|
|
|
|
if (fdh->flags & ECORE_FD_ERROR) events |= G_IO_ERR | G_IO_HUP;
|
2010-10-07 00:23:26 -07:00
|
|
|
return events;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
|
|
|
static void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_uv_poll_cb(uv_poll_t *handle, int status, int events)
|
2014-09-01 11:08:49 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Eo *obj = ML_OBJ;
|
|
|
|
Efl_Loop_Data *pd = ML_DAT;
|
2014-09-01 11:08:49 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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)
|
2014-09-01 11:08:49 -07:00
|
|
|
{
|
2017-12-21 02:31:24 -08:00
|
|
|
DBG("not IDLE anymore");
|
|
|
|
_ecore_main_uv_idling = EINA_FALSE;
|
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
|
|
|
|
_ecore_animator_run_reset();
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
|
|
|
|
2018-02-20 22:38:30 -08:00
|
|
|
if (events & UV_DISCONNECT)
|
|
|
|
{
|
|
|
|
fdh->read_active = EINA_TRUE;
|
|
|
|
fdh->write_active = EINA_TRUE;
|
|
|
|
fdh->error_active = EINA_TRUE;
|
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_try_add_to_call_list(obj, pd, fdh);
|
2014-09-01 11:08:49 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
_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);
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_ecore_main_uv_events_from_fdh(Ecore_Fd_Handler *fdh)
|
|
|
|
{
|
|
|
|
int events = 0;
|
2017-11-08 22:59:04 -08:00
|
|
|
if (fdh->flags & ECORE_FD_READ) events |= UV_READABLE;
|
2014-09-01 11:08:49 -07:00
|
|
|
if (fdh->flags & ECORE_FD_WRITE) events |= UV_WRITABLE;
|
|
|
|
DBG("events is %d", (int)events);
|
|
|
|
return events;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-10-07 00:23:26 -07:00
|
|
|
static inline int
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fdh_poll_add(Efl_Loop_Data *pd EINA_UNUSED, Ecore_Fd_Handler *fdh)
|
2010-07-27 23:08:35 -07:00
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
DBG("_ecore_main_fdh_poll_add");
|
2010-07-27 23:08:35 -07:00
|
|
|
int r = 0;
|
2011-07-06 03:54:30 -07:00
|
|
|
|
2018-02-20 22:38:30 -08:00
|
|
|
#ifdef HAVE_SYS_EPOLL_H
|
2017-11-08 22:59:04 -08:00
|
|
|
# ifdef HAVE_LIBUV
|
|
|
|
if (!_dl_uv_run)
|
|
|
|
# endif
|
2010-10-07 00:23:26 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
2010-10-07 00:23:26 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
# ifdef HAVE_LIBUV
|
2011-07-06 03:54:30 -07:00
|
|
|
else
|
2017-11-08 22:59:04 -08:00
|
|
|
# endif
|
2014-09-01 11:08:49 -07:00
|
|
|
#endif
|
2011-07-06 03:54:30 -07:00
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
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");
|
|
|
|
}
|
2014-09-01 11:08:49 -07:00
|
|
|
#elif defined(USE_G_MAIN_LOOP)
|
2011-07-06 03:54:30 -07:00
|
|
|
fdh->gfd.fd = fdh->fd;
|
|
|
|
fdh->gfd.events = _gfd_events_from_fdh(fdh);
|
|
|
|
fdh->gfd.revents = 0;
|
2013-03-16 07:08:19 -07:00
|
|
|
DBG("adding gpoll on %d %08x", fdh->fd, fdh->gfd.events);
|
2011-07-06 03:54:30 -07:00
|
|
|
g_source_add_poll(ecore_glib_source, &fdh->gfd);
|
2015-01-22 07:59:03 -08:00
|
|
|
#endif
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
2010-10-07 00:23:26 -07:00
|
|
|
return r;
|
|
|
|
}
|
2010-07-27 23:08:35 -07:00
|
|
|
|
2010-10-07 00:23:26 -07:00
|
|
|
static inline void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fdh_poll_del(Efl_Loop_Data *pd, Ecore_Fd_Handler *fdh)
|
2010-07-27 23:08:35 -07:00
|
|
|
{
|
2018-02-20 22:38:30 -08:00
|
|
|
#ifdef HAVE_SYS_EPOLL_H
|
2017-11-08 22:59:04 -08:00
|
|
|
# ifdef HAVE_LIBUV
|
|
|
|
if (!_dl_uv_run)
|
|
|
|
# endif
|
|
|
|
{
|
2018-04-04 21:18:03 -07:00
|
|
|
if (!pd)
|
|
|
|
{
|
|
|
|
WRN("Efl_Loop_Data is NULL!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2010-07-27 23:08:35 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
# ifdef HAVE_LIBUV
|
2011-07-06 03:54:30 -07:00
|
|
|
else
|
2017-11-08 22:59:04 -08:00
|
|
|
# endif
|
2014-09-01 11:08:49 -07:00
|
|
|
#endif
|
2010-10-07 00:23:26 -07:00
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
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");
|
2014-09-01 11:08:49 -07:00
|
|
|
#elif USE_G_MAIN_LOOP
|
2011-07-06 03:54:30 -07:00
|
|
|
fdh->gfd.fd = fdh->fd;
|
|
|
|
fdh->gfd.events = _gfd_events_from_fdh(fdh);
|
|
|
|
fdh->gfd.revents = 0;
|
2013-08-08 22:38:54 -07:00
|
|
|
DBG("removing gpoll on %d %08x", fdh->fd, fdh->gfd.events);
|
|
|
|
g_source_remove_poll(ecore_glib_source, &fdh->gfd);
|
2015-01-22 07:59:03 -08:00
|
|
|
#endif
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
2010-10-07 00:23:26 -07:00
|
|
|
}
|
2010-07-27 23:08:35 -07:00
|
|
|
|
2010-10-07 00:23:26 -07:00
|
|
|
static inline int
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fdh_poll_modify(Efl_Loop_Data *pd EINA_UNUSED, Ecore_Fd_Handler *fdh)
|
2010-07-27 23:08:35 -07:00
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
DBG("_ecore_main_fdh_poll_modify %p", fdh);
|
2010-07-27 23:08:35 -07:00
|
|
|
int r = 0;
|
2018-02-20 22:38:30 -08:00
|
|
|
#ifdef HAVE_SYS_EPOLL_H
|
2017-11-08 22:59:04 -08:00
|
|
|
# ifdef HAVE_LIBUV
|
|
|
|
if (!_dl_uv_run)
|
|
|
|
# endif
|
2010-10-07 00:23:26 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
|
|
|
}
|
2010-10-07 00:23:26 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
# ifdef HAVE_LIBUV
|
2011-07-06 03:54:30 -07:00
|
|
|
else
|
2017-11-08 22:59:04 -08:00
|
|
|
# endif
|
2014-09-01 11:08:49 -07:00
|
|
|
#endif
|
2011-07-06 03:54:30 -07:00
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
_dl_uv_poll_start(&fdh->uv_handle, _ecore_main_uv_events_from_fdh(fdh)
|
|
|
|
, _ecore_main_uv_poll_cb);
|
2014-09-01 11:08:49 -07:00
|
|
|
#elif defined(USE_G_MAIN_LOOP)
|
2011-07-06 03:54:30 -07:00
|
|
|
fdh->gfd.fd = fdh->fd;
|
|
|
|
fdh->gfd.events = _gfd_events_from_fdh(fdh);
|
|
|
|
fdh->gfd.revents = 0;
|
2013-03-16 07:08:19 -07:00
|
|
|
DBG("modifing gpoll on %d to %08x", fdh->fd, fdh->gfd.events);
|
2015-01-22 07:59:03 -08:00
|
|
|
#endif
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
2010-10-07 00:23:26 -07:00
|
|
|
return r;
|
|
|
|
}
|
2010-07-27 23:08:35 -07:00
|
|
|
|
2017-12-21 02:31:24 -08:00
|
|
|
static Eina_Bool
|
|
|
|
_ecore_main_idlers_exist(Efl_Loop_Data *pd)
|
|
|
|
{
|
|
|
|
return pd->idlers || eina_freeq_ptr_pending(eina_freeq_main_get());
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_main_idler_all_call(Eo *loop)
|
|
|
|
{
|
|
|
|
efl_event_callback_call(loop, EFL_LOOP_EVENT_IDLE, NULL);
|
|
|
|
// just spin in an idler until the free queue is empty freeing 84 items
|
|
|
|
// from the free queue each time.for now this seems like an ok balance
|
|
|
|
// between going in and out of a reduce func with mutexes around it
|
|
|
|
// vs blocking mainloop for too long. this number is up for discussion
|
|
|
|
eina_freeq_reduce(eina_freeq_main_get(), 84);
|
|
|
|
}
|
|
|
|
|
2018-02-20 22:38:30 -08:00
|
|
|
#ifdef HAVE_SYS_EPOLL_H
|
2011-10-20 22:40:39 -07:00
|
|
|
static inline int
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fdh_epoll_mark_active(Eo *obj, Efl_Loop_Data *pd)
|
2010-07-27 23:08:35 -07:00
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
DBG("_ecore_main_fdh_epoll_mark_active");
|
2010-08-23 06:05:57 -07:00
|
|
|
struct epoll_event ev[32];
|
2010-07-27 23:08:35 -07:00
|
|
|
int i, ret;
|
2017-11-08 22:59:04 -08:00
|
|
|
int efd = _ecore_get_epoll_fd(obj, pd);
|
2010-07-27 23:08:35 -07:00
|
|
|
|
2010-08-23 06:05:57 -07:00
|
|
|
memset(&ev, 0, sizeof (ev));
|
2010-10-20 07:15:56 -07:00
|
|
|
ret = epoll_wait(efd, ev, sizeof(ev) / sizeof(struct epoll_event), 0);
|
2010-07-27 23:08:35 -07:00
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
if (errno == EINTR) return -1;
|
2015-01-22 07:58:34 -08:00
|
|
|
ERR("epoll_wait failed on fd: %d %s", efd, strerror(errno));
|
2010-07-27 23:08:35 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-07-29 19:42:47 -07:00
|
|
|
for (i = 0; i < ret; i++)
|
2010-07-27 23:08:35 -07:00
|
|
|
{
|
2010-07-29 19:42:47 -07:00
|
|
|
Ecore_Fd_Handler *fdh;
|
2011-01-07 00:18:19 -08:00
|
|
|
|
2010-07-29 19:42:47 -07:00
|
|
|
fdh = ev[i].data.ptr;
|
2010-07-27 23:08:35 -07:00
|
|
|
if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER))
|
|
|
|
{
|
|
|
|
ECORE_MAGIC_FAIL(fdh, ECORE_MAGIC_FD_HANDLER,
|
2011-07-06 03:54:30 -07:00
|
|
|
"_ecore_main_fdh_epoll_mark_active");
|
2010-07-27 23:08:35 -07:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (fdh->delete_me)
|
|
|
|
{
|
|
|
|
ERR("deleted fd in epoll");
|
|
|
|
continue;
|
|
|
|
}
|
2011-01-28 21:34:00 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2011-01-28 21:34:00 -08:00
|
|
|
|
2018-02-20 22:38:30 -08:00
|
|
|
if (ev[i].events & EPOLLHUP)
|
|
|
|
{
|
|
|
|
fdh->read_active = EINA_TRUE;
|
|
|
|
fdh->write_active = EINA_TRUE;
|
|
|
|
fdh->error_active = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_try_add_to_call_list(obj, pd, fdh);
|
2010-07-27 23:08:35 -07:00
|
|
|
}
|
2010-08-14 04:19:03 -07:00
|
|
|
return ret;
|
|
|
|
}
|
2017-04-21 20:20:06 -07:00
|
|
|
#endif
|
2010-08-14 04:19:03 -07:00
|
|
|
|
2011-07-06 03:54:30 -07:00
|
|
|
#ifdef USE_G_MAIN_LOOP
|
2011-10-20 22:40:39 -07:00
|
|
|
static inline int
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fdh_glib_mark_active(Eo *obj, Efl_Loop_Data *pd)
|
2010-10-07 00:23:26 -07:00
|
|
|
{
|
|
|
|
Ecore_Fd_Handler *fdh;
|
|
|
|
int ret = 0;
|
|
|
|
|
2017-12-14 21:36:30 -08:00
|
|
|
// call the prepare callback for all handlers
|
2017-11-08 22:59:04 -08:00
|
|
|
EINA_INLIST_FOREACH(pd->fd_handlers, fdh)
|
2010-10-07 00:23:26 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
if (fdh->delete_me) continue;
|
2010-11-30 19:45:22 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2011-01-28 21:34:00 -08:00
|
|
|
|
2018-02-20 22:38:30 -08:00
|
|
|
if (fdh->gfd.revents & G_IO_HUP)
|
|
|
|
{
|
|
|
|
fdh->read_active = EINA_TRUE;
|
|
|
|
fdh->write_active = EINA_TRUE;
|
|
|
|
fdh->error_active = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_try_add_to_call_list(obj, fdh);
|
2011-01-28 21:34:00 -08:00
|
|
|
|
2011-10-20 22:40:39 -07:00
|
|
|
if (fdh->gfd.revents & (G_IO_IN | G_IO_OUT | G_IO_ERR)) ret++;
|
2010-10-07 00:23:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-12-14 21:36:30 -08:00
|
|
|
// like we are about to enter main_loop_select in _ecore_main_select
|
2010-08-14 04:19:03 -07:00
|
|
|
static gboolean
|
2012-11-25 01:55:32 -08:00
|
|
|
_ecore_main_gsource_prepare(GSource *source EINA_UNUSED,
|
2011-10-20 22:40:39 -07:00
|
|
|
gint *next_time)
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Eo *obj = ML_OBJ;
|
|
|
|
Efl_Loop_Data *pd = ML_DAT;
|
2011-07-11 23:11:14 -07:00
|
|
|
gboolean ready = FALSE;
|
2010-08-14 04:19:03 -07:00
|
|
|
|
|
|
|
in_main_loop++;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop = in_main_loop;
|
2010-08-14 04:19:03 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if ((!ecore_idling) && (!_ecore_glib_idle_enterer_called))
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->loop_time = _ecore_time_loop_time = ecore_time_get();
|
|
|
|
_efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time);
|
2011-07-26 19:34:53 -07:00
|
|
|
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_ENTER, NULL);
|
2011-07-12 04:57:03 -07:00
|
|
|
_ecore_throttle();
|
2017-11-08 22:59:04 -08:00
|
|
|
_throttle_do(pd);
|
2011-07-12 04:57:03 -07:00
|
|
|
_ecore_glib_idle_enterer_called = FALSE;
|
2011-07-26 20:13:47 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (pd->fd_handlers_with_buffer)
|
|
|
|
_ecore_main_fd_handlers_buf_call(obj, pd);
|
2010-08-14 04:19:03 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_signal_received_process(obj, pd);
|
2011-07-08 01:07:40 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// don't check fds if somebody quit
|
2011-07-11 23:11:14 -07:00
|
|
|
if (g_main_loop_is_running(ecore_main_loop))
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// only set idling state in dispatch
|
2017-12-21 02:31:24 -08:00
|
|
|
if (ecore_idling && (!_ecore_main_idlers_exist(pd)) &&
|
|
|
|
(!pd->message_queue))
|
2017-11-08 22:59:04 -08:00
|
|
|
{
|
|
|
|
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;
|
2017-12-21 02:31:24 -08:00
|
|
|
if (pd->message_queue) ready = TRUE;
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pd->fd_handlers_with_prep) _ecore_main_prepare_handlers(obj, pd);
|
2010-08-14 04:19:03 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
else ready = TRUE;
|
2010-08-14 04:19:03 -07:00
|
|
|
|
|
|
|
in_main_loop--;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop = in_main_loop;
|
2015-01-20 10:13:29 -08:00
|
|
|
DBG("leave, timeout = %d", *next_time);
|
2010-08-14 04:19:03 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// ready if we're not running (about to quit)
|
2011-07-11 23:11:14 -07:00
|
|
|
return ready;
|
2010-08-14 04:19:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2012-11-25 01:55:32 -08:00
|
|
|
_ecore_main_gsource_check(GSource *source EINA_UNUSED)
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Eo *obj = ML_OBJ;
|
|
|
|
Efl_Loop_Data *pd = ML_DAT;
|
2011-07-05 04:13:39 -07:00
|
|
|
gboolean ret = FALSE;
|
|
|
|
|
2010-08-14 04:19:03 -07:00
|
|
|
in_main_loop++;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop = in_main_loop;
|
|
|
|
// check if old timers expired
|
2017-12-21 02:31:24 -08:00
|
|
|
if (ecore_idling && (!_ecore_main_idlers_exist(pd)) &&
|
|
|
|
(!pd->message_queue))
|
2011-07-05 04:13:39 -07:00
|
|
|
{
|
2011-07-06 03:54:11 -07:00
|
|
|
if (timer_fd >= 0)
|
2011-07-05 04:13:39 -07:00
|
|
|
{
|
2011-07-06 03:54:11 -07:00
|
|
|
uint64_t count = 0;
|
|
|
|
int r = read(timer_fd, &count, sizeof count);
|
2017-04-21 20:20:06 -07:00
|
|
|
if ((r == -1) && (errno == EAGAIN))
|
2017-11-08 22:59:04 -08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
else if (r == sizeof count) ret = TRUE;
|
2011-07-06 03:54:11 -07:00
|
|
|
else
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// unexpected things happened... fail back to old way
|
|
|
|
ERR("timer read returned %d (errno=%d)", r, errno);
|
|
|
|
close(timer_fd);
|
|
|
|
timer_fd = -1;
|
2011-07-06 03:54:11 -07:00
|
|
|
}
|
2011-07-05 04:13:39 -07:00
|
|
|
}
|
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
else ret = TRUE;
|
2011-07-05 04:13:39 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// check if fds are ready
|
2018-02-20 22:38:30 -08:00
|
|
|
#ifdef HAVE_SYS_EPOLL_H
|
2017-11-08 22:59:04 -08:00
|
|
|
if (pd->epoll_fd >= 0)
|
|
|
|
ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active(obj, pd) > 0);
|
2011-07-06 03:54:30 -07:00
|
|
|
else
|
2017-04-21 20:20:06 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2011-07-04 19:31:58 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// check timers after updating loop time
|
|
|
|
if (!ret && _efl_loop_timers_exists(obj, pd))
|
|
|
|
ret = (0.0 == _efl_loop_timer_next_get(obj, pd));
|
2011-07-06 03:54:30 -07:00
|
|
|
|
2010-08-14 04:19:03 -07:00
|
|
|
in_main_loop--;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop = in_main_loop;
|
2011-07-12 04:56:36 -07:00
|
|
|
return ret;
|
2010-08-14 04:19:03 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// like we just came out of main_loop_select in _ecore_main_select
|
2010-08-14 04:19:03 -07:00
|
|
|
static gboolean
|
2012-11-25 01:55:32 -08:00
|
|
|
_ecore_main_gsource_dispatch(GSource *source EINA_UNUSED,
|
|
|
|
GSourceFunc callback EINA_UNUSED,
|
|
|
|
gpointer user_data EINA_UNUSED)
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Eo *obj = ML_OBJ;
|
|
|
|
Efl_Loop_Data *pd = ML_DAT;
|
2011-07-08 03:26:14 -07:00
|
|
|
gboolean events_ready, timers_ready, idlers_ready;
|
2011-07-12 04:56:54 -07:00
|
|
|
double next_time;
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->loop_time = ecore_time_get();
|
|
|
|
_efl_loop_timer_enable_new(obj, pd);
|
|
|
|
next_time = _efl_loop_timer_next_get(obj, pd);
|
2010-08-14 04:19:03 -07:00
|
|
|
|
2017-12-21 02:31:24 -08:00
|
|
|
events_ready = pd->message_queue ? 1 : 0;
|
2017-11-08 22:59:04 -08:00
|
|
|
timers_ready = _efl_loop_timers_exists(obj, pd) && (0.0 == next_time);
|
2017-12-21 02:31:24 -08:00
|
|
|
idlers_ready = _ecore_main_idlers_exist(pd);
|
2010-08-14 04:19:03 -07:00
|
|
|
|
|
|
|
in_main_loop++;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop = in_main_loop;
|
2015-01-20 10:13:29 -08:00
|
|
|
DBG("enter idling=%d fds=%d events=%d timers=%d (next=%.2f) idlers=%d",
|
2011-07-08 03:26:14 -07:00
|
|
|
ecore_idling, ecore_fds_ready, events_ready,
|
2011-06-12 19:58:20 -07:00
|
|
|
timers_ready, next_time, idlers_ready);
|
2010-08-14 04:19:03 -07:00
|
|
|
|
|
|
|
if (ecore_idling && events_ready)
|
|
|
|
{
|
2013-12-07 22:05:51 -08:00
|
|
|
_ecore_animator_run_reset();
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
|
2010-08-14 04:19:03 -07:00
|
|
|
ecore_idling = 0;
|
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
else if (!ecore_idling && !events_ready) ecore_idling = 1;
|
2010-08-14 04:19:03 -07:00
|
|
|
|
|
|
|
if (ecore_idling)
|
|
|
|
{
|
2017-12-21 02:31:24 -08:00
|
|
|
_ecore_main_idler_all_call(obj);
|
2010-08-14 04:19:03 -07:00
|
|
|
|
2017-12-21 02:31:24 -08:00
|
|
|
events_ready = pd->message_queue ? 1 : 0;
|
2010-08-14 04:19:03 -07:00
|
|
|
|
2011-07-08 03:26:24 -07:00
|
|
|
if (ecore_fds_ready || events_ready || timers_ready)
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
2013-12-07 22:05:51 -08:00
|
|
|
_ecore_animator_run_reset();
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
|
2010-08-14 04:19:03 -07:00
|
|
|
ecore_idling = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// process events
|
2010-08-14 04:19:03 -07:00
|
|
|
if (!ecore_idling)
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
_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);
|
2011-07-12 04:56:54 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
_efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time);
|
2011-07-12 04:57:03 -07:00
|
|
|
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_ENTER, NULL);
|
2011-07-12 04:57:03 -07:00
|
|
|
_ecore_throttle();
|
2017-11-08 22:59:04 -08:00
|
|
|
_throttle_do(pd);
|
2011-07-12 04:57:03 -07:00
|
|
|
_ecore_glib_idle_enterer_called = TRUE;
|
2011-07-26 20:13:47 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (pd->fd_handlers_with_buffer)
|
|
|
|
_ecore_main_fd_handlers_buf_call(obj, pd);
|
2010-08-14 04:19:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
in_main_loop--;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop = in_main_loop;
|
2010-08-14 04:19:03 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
return TRUE; // what should be returned here?
|
2010-08-14 04:19:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-11-25 01:55:32 -08:00
|
|
|
_ecore_main_gsource_finalize(GSource *source EINA_UNUSED)
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-09-13 17:53:57 -07:00
|
|
|
static GSourceFuncs ecore_gsource_funcs =
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
.prepare = _ecore_main_gsource_prepare,
|
|
|
|
.check = _ecore_main_gsource_check,
|
2010-08-14 04:19:03 -07:00
|
|
|
.dispatch = _ecore_main_gsource_dispatch,
|
|
|
|
.finalize = _ecore_main_gsource_finalize,
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
#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);
|
2013-08-08 20:02:04 -07:00
|
|
|
|
|
|
|
static void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_loop_timer_run(uv_timer_t *timer EINA_UNUSED)
|
2013-08-08 20:02:04 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Eo *obj = ML_OBJ;
|
|
|
|
Efl_Loop_Data *pd = ML_DAT;
|
2013-08-08 20:02:04 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (_ecore_main_uv_idling)
|
2013-08-08 20:02:04 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_uv_idling = EINA_FALSE;
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_animator_run_reset();
|
2013-08-08 20:02:04 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->loop_time = ecore_time_get();
|
|
|
|
_ecore_main_loop_uv_check(NULL);
|
|
|
|
_ecore_main_loop_uv_prepare(NULL);
|
2013-08-08 20:02:04 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
static inline void
|
|
|
|
_ecore_main_loop_uv_check(uv_check_t *handle EINA_UNUSED)
|
2013-08-08 20:02:04 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Eo *obj = ML_OBJ;
|
|
|
|
Efl_Loop_Data *pd = ML_DAT;
|
2013-08-08 20:02:04 -07:00
|
|
|
|
2014-09-01 11:08:49 -07:00
|
|
|
DBG("_ecore_main_loop_uv_check idling? %d", (int)_ecore_main_uv_idling);
|
|
|
|
in_main_loop++;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop = in_main_loop;
|
2014-09-01 11:08:49 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (pd->do_quit) goto quit;
|
2016-01-14 14:52:37 -08:00
|
|
|
|
2014-09-01 11:08:49 -07:00
|
|
|
do
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
_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);
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
while (pd->fd_handlers_to_call);
|
2016-01-14 14:52:37 -08:00
|
|
|
quit:
|
2014-09-01 11:08:49 -07:00
|
|
|
in_main_loop--;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop = in_main_loop;
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
static void
|
|
|
|
_ecore_main_loop_setup(Eo *obj, Efl_Loop_Data *pd)
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// Please note that this function is being also called in case of a bad
|
|
|
|
// fd to reset the main loop.
|
2018-02-20 22:38:30 -08:00
|
|
|
#ifdef HAVE_SYS_EPOLL_H
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->epoll_fd = epoll_create(1);
|
|
|
|
if (pd->epoll_fd < 0) WRN("Failed to create epoll fd!");
|
2017-04-21 20:20:06 -07:00
|
|
|
else
|
2010-10-20 07:15:56 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
eina_file_close_on_exec(pd->epoll_fd, EINA_TRUE);
|
2017-04-21 20:20:06 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->epoll_pid = getpid();
|
2017-04-21 20:20:06 -07:00
|
|
|
|
2017-12-14 21:36:30 -08:00
|
|
|
// add polls on all our file descriptors
|
2017-04-21 20:20:06 -07:00
|
|
|
Ecore_Fd_Handler *fdh;
|
2017-11-08 22:59:04 -08:00
|
|
|
EINA_INLIST_FOREACH(pd->fd_handlers, fdh)
|
2017-04-21 20:20:06 -07:00
|
|
|
{
|
|
|
|
if (fdh->delete_me) continue;
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_epoll_add(pd->epoll_fd, fdh->fd,
|
2017-04-21 20:20:06 -07:00
|
|
|
_ecore_poll_events_from_fdh(fdh), fdh);
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fdh_poll_add(pd, fdh);
|
2017-04-21 20:20:06 -07:00
|
|
|
}
|
2010-10-20 07:15:56 -07:00
|
|
|
}
|
2017-04-21 20:20:06 -07:00
|
|
|
#endif
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (obj == ML_OBJ)
|
2010-09-13 17:53:57 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
#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"))
|
2011-07-06 03:54:30 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
2011-07-06 03:54:30 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
// else
|
|
|
|
// DBG("did not load uv");
|
|
|
|
DBG("loaded dlsyms uv");
|
2017-04-21 20:20:06 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
|
|
|
|
// 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!");
|
2011-10-20 22:40:39 -07:00
|
|
|
else
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
g_source_set_priority(ecore_glib_source,
|
|
|
|
G_PRIORITY_HIGH_IDLE + 20);
|
2018-02-20 22:38:30 -08:00
|
|
|
# ifdef HAVE_SYS_EPOLL_H
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
|
|
|
}
|
2011-07-06 03:54:11 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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");
|
|
|
|
}
|
2010-08-14 04:19:03 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
_ecore_main_timechanges_start(obj);
|
2010-07-27 23:08:35 -07:00
|
|
|
}
|
2010-08-14 04:19:03 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
static void
|
|
|
|
_ecore_main_loop_clear(Eo *obj, Efl_Loop_Data *pd)
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
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)
|
2010-09-13 17:53:57 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_timechanges_stop(obj);
|
|
|
|
#ifdef USE_G_MAIN_LOOP
|
|
|
|
if (ecore_glib_source)
|
|
|
|
{
|
|
|
|
g_source_destroy(ecore_glib_source);
|
|
|
|
ecore_glib_source = NULL;
|
|
|
|
}
|
2010-07-27 23:08:35 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
#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);
|
|
|
|
}
|
2017-04-21 20:20:06 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
2018-02-20 22:38:30 -08:00
|
|
|
# ifdef HAVE_SYS_EPOLL_H
|
2017-11-08 22:59:04 -08:00
|
|
|
if (pd->epoll_fd >= 0)
|
2011-07-06 03:54:11 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
close(pd->epoll_fd);
|
|
|
|
pd->epoll_fd = -1;
|
2011-07-06 03:54:11 -07:00
|
|
|
}
|
2017-12-23 04:07:23 -08:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
if (pd->timer_fd >= 0)
|
2014-09-01 11:08:49 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
close(pd->timer_fd);
|
|
|
|
pd->timer_fd = -1;
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
2010-08-14 04:19:03 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
void
|
|
|
|
_ecore_main_loop_init(void)
|
2011-08-11 22:22:07 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
DBG("_ecore_main_loop_init");
|
2018-02-26 21:10:12 -08:00
|
|
|
if (!efl_main_loop_get()) ERR("Cannot create main loop object");
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_loop_setup(ML_OBJ, ML_DAT);
|
|
|
|
}
|
2011-08-11 22:22:07 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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?
|
2018-03-19 15:33:11 -07:00
|
|
|
efl_unref(ML_OBJ);
|
2011-08-11 22:22:07 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
void
|
|
|
|
_ecore_main_loop_iterate(Eo *obj, Efl_Loop_Data *pd)
|
2012-04-10 02:12:12 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
if (obj == ML_OBJ)
|
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
if (!_dl_uv_run)
|
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
#endif
|
2012-04-10 02:12:12 -07:00
|
|
|
#ifndef USE_G_MAIN_LOOP
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->loop_time = ecore_time_get();
|
|
|
|
_ecore_main_loop_iterate_internal(obj, pd, 1);
|
2012-04-10 02:12:12 -07:00
|
|
|
#else
|
2017-11-08 22:59:04 -08:00
|
|
|
g_main_context_iteration(NULL, 0);
|
2012-04-10 02:12:12 -07:00
|
|
|
#endif
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
_dl_uv_run(_dl_uv_default_loop(), UV_RUN_ONCE | UV_RUN_NOWAIT);
|
2014-09-01 11:08:49 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pd->loop_time = ecore_time_get();
|
|
|
|
_ecore_main_loop_iterate_internal(obj, pd, 1);
|
|
|
|
}
|
2012-04-10 02:12:12 -07:00
|
|
|
}
|
2012-02-01 21:21:24 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
int
|
|
|
|
_ecore_main_loop_iterate_may_block(Eo *obj, Efl_Loop_Data *pd, int may_block)
|
2012-02-01 21:21:24 -08:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
if (obj == ML_OBJ)
|
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
if (!_dl_uv_run)
|
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
#endif
|
2012-02-01 21:21:24 -08:00
|
|
|
#ifndef USE_G_MAIN_LOOP
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2017-12-21 02:31:24 -08:00
|
|
|
return pd->message_queue ? 1 : 0;
|
2012-02-01 21:21:24 -08:00
|
|
|
#else
|
2017-11-08 22:59:04 -08:00
|
|
|
return g_main_context_iteration(NULL, may_block);
|
2012-02-01 21:21:24 -08:00
|
|
|
#endif
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
_dl_uv_run(_dl_uv_default_loop(),
|
|
|
|
may_block ? (UV_RUN_ONCE | UV_RUN_NOWAIT) : UV_RUN_ONCE);
|
2014-09-01 11:08:49 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pd->in_loop++;
|
|
|
|
pd->loop_time = ecore_time_get();
|
|
|
|
_ecore_main_loop_iterate_internal(obj, pd, !may_block);
|
|
|
|
pd->in_loop--;
|
2017-12-21 02:31:24 -08:00
|
|
|
return pd->message_queue ? 1 : 0;
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
return 0;
|
2012-02-01 21:21:24 -08:00
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
void
|
|
|
|
_ecore_main_loop_begin(Eo *obj, Efl_Loop_Data *pd)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
if (obj == ML_OBJ)
|
2015-10-05 00:00:47 -07:00
|
|
|
{
|
2013-03-10 04:53:58 -07:00
|
|
|
#ifdef HAVE_SYSTEMD
|
2017-11-08 22:59:04 -08:00
|
|
|
sd_notify(0, "READY=1");
|
2013-03-10 04:53:58 -07:00
|
|
|
#endif
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
if (!_dl_uv_run)
|
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
#endif
|
2010-08-14 04:19:03 -07:00
|
|
|
#ifndef USE_G_MAIN_LOOP
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2010-08-14 04:19:03 -07:00
|
|
|
#else
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2014-09-01 11:08:49 -07:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LIBUV
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
2014-09-01 11:08:49 -07:00
|
|
|
else
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
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--;
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
2010-08-14 04:19:03 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2015-05-10 03:05:54 -07:00
|
|
|
eina_evlog("-mainloop", NULL, 0.0, NULL);
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_main_loop_quit(void)
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Eina_Value v = EINA_VALUE_EMPTY;
|
|
|
|
|
|
|
|
eina_value_setup(&v, EINA_VALUE_TYPE_INT);
|
2018-04-22 05:38:12 -07:00
|
|
|
eina_value_set(&v, 0);
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2017-11-08 22:59:04 -08:00
|
|
|
efl_loop_quit(ML_OBJ, v);
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
EAPI int
|
2014-12-04 05:56:43 -08:00
|
|
|
ecore_main_loop_nested_get(void)
|
|
|
|
{
|
|
|
|
return in_main_loop;
|
|
|
|
}
|
|
|
|
|
2013-12-07 22:05:51 -08:00
|
|
|
EAPI Eina_Bool
|
|
|
|
ecore_main_loop_animator_ticked_get(void)
|
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
DBG("ecore_main_loop_animator_ticked_get");
|
2013-12-07 22:05:51 -08:00
|
|
|
return _ecore_animator_run_get();
|
|
|
|
}
|
|
|
|
|
2009-04-16 08:44:26 -07:00
|
|
|
EAPI void
|
2010-08-03 19:55:20 -07:00
|
|
|
ecore_main_loop_select_func_set(Ecore_Select_Function func)
|
2009-04-16 08:44:26 -07:00
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2009-04-16 08:44:26 -07:00
|
|
|
main_loop_select = func;
|
|
|
|
}
|
|
|
|
|
2011-01-22 02:11:14 -08:00
|
|
|
EAPI Ecore_Select_Function
|
2009-04-16 08:44:26 -07:00
|
|
|
ecore_main_loop_select_func_get(void)
|
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
|
2009-04-16 08:44:26 -07:00
|
|
|
return main_loop_select;
|
|
|
|
}
|
|
|
|
|
2012-11-06 02:49:05 -08:00
|
|
|
Ecore_Fd_Handler *
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fd_handler_add(Eo *obj,
|
|
|
|
Efl_Loop_Data *pd,
|
|
|
|
Eo *handler,
|
|
|
|
int fd,
|
2012-11-06 02:49:05 -08:00
|
|
|
Ecore_Fd_Handler_Flags flags,
|
|
|
|
Ecore_Fd_Cb func,
|
|
|
|
const void *data,
|
|
|
|
Ecore_Fd_Cb buf_func,
|
2015-04-07 20:06:58 -07:00
|
|
|
const void *buf_data,
|
|
|
|
Eina_Bool is_file)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2014-09-01 11:08:49 -07:00
|
|
|
DBG("_ecore_main_fd_handler_add");
|
2011-07-28 05:01:16 -07:00
|
|
|
Ecore_Fd_Handler *fdh = NULL;
|
2003-09-23 01:09:32 -07:00
|
|
|
|
2018-01-31 01:04:09 -08:00
|
|
|
if ((fd < 0) || (flags == 0) || (!func)) return NULL;
|
2011-01-07 00:18:19 -08:00
|
|
|
|
2011-12-02 19:39:07 -08:00
|
|
|
fdh = ecore_fd_handler_calloc(1);
|
2012-11-06 02:49:05 -08:00
|
|
|
if (!fdh) return NULL;
|
2003-09-23 01:09:32 -07:00
|
|
|
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
|
2017-11-08 22:59:04 -08:00
|
|
|
fdh->loop = obj;
|
|
|
|
fdh->loop_data = pd;
|
|
|
|
fdh->handler = handler;
|
2003-09-23 01:09:32 -07:00
|
|
|
fdh->fd = fd;
|
|
|
|
fdh->flags = flags;
|
2015-04-07 20:06:58 -07:00
|
|
|
fdh->file = is_file;
|
2017-11-08 22:59:04 -08:00
|
|
|
if (_ecore_main_fdh_poll_add(pd, fdh) < 0)
|
2010-07-27 23:08:35 -07:00
|
|
|
{
|
2011-01-20 14:37:57 -08:00
|
|
|
int err = errno;
|
2017-11-08 22:59:04 -08:00
|
|
|
ERR("Failed to add poll on fd %d (errno = %d: %s)!",
|
|
|
|
fd, err, strerror(err));
|
2011-12-02 19:39:07 -08:00
|
|
|
ecore_fd_handler_mp_free(fdh);
|
2012-11-06 02:49:05 -08:00
|
|
|
return NULL;
|
2010-07-27 23:08:35 -07:00
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
fdh->func = func;
|
|
|
|
fdh->data = (void *)data;
|
|
|
|
fdh->buf_func = buf_func;
|
2010-11-16 22:50:52 -08:00
|
|
|
if (buf_func)
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->fd_handlers_with_buffer = eina_list_append
|
|
|
|
(pd->fd_handlers_with_buffer, fdh);
|
2003-09-23 01:09:32 -07:00
|
|
|
fdh->buf_data = (void *)buf_data;
|
2016-03-31 10:27:29 -07:00
|
|
|
if (is_file)
|
2017-11-08 22:59:04 -08:00
|
|
|
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),
|
2011-10-20 22:40:39 -07:00
|
|
|
EINA_INLIST_GET(fdh));
|
2003-09-23 01:09:32 -07:00
|
|
|
return fdh;
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-11-06 02:49:05 -08:00
|
|
|
EAPI Ecore_Fd_Handler *
|
|
|
|
ecore_main_fd_handler_add(int fd,
|
|
|
|
Ecore_Fd_Handler_Flags flags,
|
|
|
|
Ecore_Fd_Cb func,
|
|
|
|
const void *data,
|
|
|
|
Ecore_Fd_Cb buf_func,
|
|
|
|
const void *buf_data)
|
|
|
|
{
|
|
|
|
Ecore_Fd_Handler *fdh = NULL;
|
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
|
2018-02-27 04:19:17 -08:00
|
|
|
fdh = _ecore_main_fd_handler_add(efl_main_loop_get(),
|
2017-11-08 22:59:04 -08:00
|
|
|
ML_DAT, NULL, fd, flags, func, data,
|
|
|
|
buf_func, buf_data, EINA_FALSE);
|
2018-02-21 02:05:48 -08:00
|
|
|
if (fdh) fdh->legacy = EINA_TRUE;
|
2012-11-06 02:49:05 -08:00
|
|
|
return fdh;
|
|
|
|
}
|
|
|
|
|
2012-08-01 07:37:24 -07:00
|
|
|
EAPI Ecore_Fd_Handler *
|
|
|
|
ecore_main_fd_handler_file_add(int fd,
|
|
|
|
Ecore_Fd_Handler_Flags flags,
|
|
|
|
Ecore_Fd_Cb func,
|
|
|
|
const void *data,
|
|
|
|
Ecore_Fd_Cb buf_func,
|
|
|
|
const void *buf_data)
|
|
|
|
{
|
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
|
2018-02-27 04:19:17 -08:00
|
|
|
return _ecore_main_fd_handler_add(efl_main_loop_get(),
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
2012-08-01 07:37:24 -07:00
|
|
|
}
|
|
|
|
|
2009-10-25 00:07:48 -07:00
|
|
|
#ifdef _WIN32
|
|
|
|
EAPI Ecore_Win32_Handler *
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_win32_handler_add(Eo *obj,
|
|
|
|
Efl_Loop_Data *pd,
|
|
|
|
Eo *handler,
|
|
|
|
void *h,
|
|
|
|
Ecore_Win32_Handle_Cb func,
|
|
|
|
const void *data)
|
|
|
|
{
|
2009-10-25 00:07:48 -07:00
|
|
|
Ecore_Win32_Handler *wh;
|
|
|
|
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
|
2010-05-18 01:01:06 -07:00
|
|
|
if (!h || !func) return NULL;
|
2009-10-25 00:07:48 -07:00
|
|
|
|
2015-09-24 22:32:32 -07:00
|
|
|
wh = ecore_win32_handler_calloc(1);
|
2009-10-25 00:07:48 -07:00
|
|
|
if (!wh) return NULL;
|
|
|
|
ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER);
|
2017-11-08 22:59:04 -08:00
|
|
|
wh->loop = obj;
|
|
|
|
wh->loop_data = pd;
|
2017-12-16 22:07:37 -08:00
|
|
|
wh->handler = handler;
|
2009-10-25 00:07:48 -07:00
|
|
|
wh->h = (HANDLE)h;
|
|
|
|
wh->func = func;
|
|
|
|
wh->data = (void *)data;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->win32_handlers = (Ecore_Win32_Handler *)
|
|
|
|
eina_inlist_append(EINA_INLIST_GET(pd->win32_handlers),
|
2011-10-20 22:40:39 -07:00
|
|
|
EINA_INLIST_GET(wh));
|
2009-10-25 00:07:48 -07:00
|
|
|
return wh;
|
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
void *
|
2017-12-16 22:07:37 -08:00
|
|
|
_ecore_main_win32_handler_del(Eo *obj EINA_UNUSED,
|
|
|
|
Efl_Loop_Data *pd,
|
|
|
|
Ecore_Win32_Handler *win32_handler)
|
2015-10-08 13:32:57 -07:00
|
|
|
{
|
|
|
|
if (win32_handler->delete_me)
|
|
|
|
{
|
|
|
|
ERR("win32 handler %p deleted twice", win32_handler);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
win32_handler->delete_me = EINA_TRUE;
|
2017-11-08 22:59:04 -08:00
|
|
|
win32_handler->handler = NULL;
|
|
|
|
pd->win32_handlers_to_delete = eina_list_append
|
|
|
|
(pd->win32_handlers_to_delete, win32_handler);
|
2015-10-08 13:32:57 -07:00
|
|
|
return win32_handler->data;
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
2017-12-16 22:07:37 -08:00
|
|
|
return _ecore_main_win32_handler_add(ML_OBJ, ML_DAT, NULL, h, func, data);
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
|
2009-11-23 15:09:48 -08:00
|
|
|
EAPI void *
|
|
|
|
ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler)
|
|
|
|
{
|
2015-10-08 13:32:57 -07:00
|
|
|
void *ret = NULL;
|
|
|
|
|
2012-12-24 01:35:56 -08:00
|
|
|
if (!win32_handler) return NULL;
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
|
2009-11-23 15:09:48 -08:00
|
|
|
if (!ECORE_MAGIC_CHECK(win32_handler, ECORE_MAGIC_WIN32_HANDLER))
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
ECORE_MAGIC_FAIL(win32_handler, ECORE_MAGIC_WIN32_HANDLER,
|
|
|
|
"ecore_main_win32_handler_del");
|
|
|
|
return NULL;
|
2009-11-23 15:09:48 -08:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
ret = _ecore_main_win32_handler_del(ML_OBJ, ML_DAT, win32_handler);
|
2015-10-08 13:32:57 -07:00
|
|
|
return ret;
|
2009-11-23 15:09:48 -08:00
|
|
|
}
|
|
|
|
#else
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2009-11-23 15:09:48 -08:00
|
|
|
EAPI void *
|
2012-11-25 01:55:32 -08:00
|
|
|
ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler EINA_UNUSED)
|
2009-11-23 15:09:48 -08:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler,
|
|
|
|
Ecore_Fd_Prep_Cb func,
|
|
|
|
const void *data)
|
2005-03-28 00:55:59 -08:00
|
|
|
{
|
2018-01-22 04:27:08 -08:00
|
|
|
if (!fd_handler) return;
|
2017-11-08 22:59:04 -08:00
|
|
|
Efl_Loop_Data *pd = fd_handler->loop_data;
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2011-07-05 04:13:29 -07:00
|
|
|
|
2005-03-28 00:55:59 -08:00
|
|
|
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
|
|
|
|
"ecore_main_fd_handler_prepare_callback_set");
|
2017-11-08 22:59:04 -08:00
|
|
|
return;
|
2005-03-28 00:55:59 -08:00
|
|
|
}
|
|
|
|
fd_handler->prep_func = func;
|
2010-10-07 00:23:26 -07:00
|
|
|
fd_handler->prep_data = (void *)data;
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
2005-03-28 00:55:59 -08:00
|
|
|
}
|
|
|
|
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI int
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
|
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1);
|
2011-07-28 05:01:16 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
|
|
|
|
"ecore_main_fd_handler_fd_get");
|
2016-01-14 14:52:37 -08:00
|
|
|
return -1;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2016-01-14 14:52:37 -08:00
|
|
|
return fd_handler->fd;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
|
2010-09-20 19:06:41 -07:00
|
|
|
EAPI Eina_Bool
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler,
|
|
|
|
Ecore_Fd_Handler_Flags flags)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2010-09-20 19:06:41 -07:00
|
|
|
int ret = EINA_FALSE;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
|
2011-07-05 04:13:29 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
|
|
|
|
"ecore_main_fd_handler_active_get");
|
2016-01-14 14:52:37 -08:00
|
|
|
return EINA_FALSE;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE;
|
2010-09-20 19:06:41 -07:00
|
|
|
if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE;
|
|
|
|
if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE;
|
2003-09-23 01:09:32 -07:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2006-01-06 09:58:12 -08:00
|
|
|
EAPI void
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler,
|
|
|
|
Ecore_Fd_Handler_Flags flags)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
int ret = -1;
|
2011-07-05 04:13:29 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
|
|
|
|
"ecore_main_fd_handler_active_set");
|
2017-11-08 22:59:04 -08:00
|
|
|
return;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
fd_handler->flags = flags;
|
2017-11-08 22:59:04 -08:00
|
|
|
if (fd_handler->loop_data)
|
|
|
|
ret = _ecore_main_fdh_poll_modify(fd_handler->loop_data, fd_handler);
|
2011-02-15 11:51:06 -08:00
|
|
|
if (ret < 0)
|
2017-11-08 22:59:04 -08:00
|
|
|
ERR("Failed to mod epoll fd %d, loop data=%p: %s!",
|
|
|
|
fd_handler->fd, fd_handler->loop_data, strerror(errno));
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-02-27 04:19:17 -08:00
|
|
|
_ecore_main_content_clear(Eo *obj, Efl_Loop_Data *pd)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2018-02-27 04:19:17 -08:00
|
|
|
__eina_promise_cancel_data(obj);
|
2017-12-15 02:09:02 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
while (pd->fd_handlers)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Ecore_Fd_Handler *fdh = pd->fd_handlers;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->fd_handlers = (Ecore_Fd_Handler *)
|
|
|
|
eina_inlist_remove(EINA_INLIST_GET(pd->fd_handlers),
|
|
|
|
EINA_INLIST_GET(fdh));
|
2018-02-20 22:45:55 -08:00
|
|
|
if ((fdh->handler) && (fdh->legacy)) efl_del(fdh->handler);
|
2017-11-08 22:59:04 -08:00
|
|
|
else
|
|
|
|
{
|
2017-12-23 04:07:23 -08:00
|
|
|
// XXX: can't do this because this fd handler is legacy and might
|
|
|
|
// be cleaned up later in object destructors
|
|
|
|
// ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
|
|
|
|
// ecore_fd_handler_mp_free(fdh);
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
}
|
2017-12-23 04:07:23 -08:00
|
|
|
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;
|
2017-11-08 22:59:04 -08:00
|
|
|
|
|
|
|
pd->do_quit = 0;
|
2009-11-23 15:09:48 -08:00
|
|
|
|
|
|
|
#ifdef _WIN32
|
2017-11-08 22:59:04 -08:00
|
|
|
while (pd->win32_handlers)
|
2009-11-23 15:09:48 -08:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Ecore_Win32_Handler *wh = pd->win32_handlers;
|
2009-11-23 15:09:48 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->win32_handlers = (Ecore_Win32_Handler *)
|
|
|
|
eina_inlist_remove(EINA_INLIST_GET(pd->win32_handlers),
|
|
|
|
EINA_INLIST_GET(wh));
|
2017-12-16 23:03:33 -08:00
|
|
|
if (wh->handler) efl_del(wh->handler);
|
2017-11-08 22:59:04 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
|
|
|
|
ecore_win32_handler_mp_free(wh);
|
|
|
|
}
|
2009-11-23 15:09:48 -08:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
if (pd->win32_handlers_to_delete)
|
|
|
|
pd->win32_handlers_to_delete =
|
|
|
|
eina_list_free(pd->win32_handlers_to_delete);
|
|
|
|
pd->win32_handler_current = NULL;
|
2009-11-23 15:09:48 -08:00
|
|
|
#endif
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-14 04:19:03 -07:00
|
|
|
static void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_prepare_handlers(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
|
|
|
Ecore_Fd_Handler *fdh;
|
2010-11-16 22:24:49 -08:00
|
|
|
Eina_List *l, *l2;
|
2010-08-14 04:19:03 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// call the prepare callback for all handlers with prep functions
|
|
|
|
EINA_LIST_FOREACH_SAFE(pd->fd_handlers_with_prep, l, l2, fdh)
|
2010-08-14 04:19:03 -07:00
|
|
|
{
|
2010-12-01 02:31:20 -08:00
|
|
|
if (!fdh)
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->fd_handlers_with_prep = eina_list_remove_list
|
|
|
|
(l, pd->fd_handlers_with_prep);
|
2010-12-01 02:31:20 -08:00
|
|
|
continue;
|
|
|
|
}
|
2010-08-14 04:19:03 -07:00
|
|
|
if (!fdh->delete_me && fdh->prep_func)
|
|
|
|
{
|
|
|
|
fdh->references++;
|
2011-08-11 03:59:48 -07:00
|
|
|
_ecore_call_prep_cb(fdh->prep_func, fdh->prep_data, fdh);
|
2010-08-14 04:19:03 -07:00
|
|
|
fdh->references--;
|
|
|
|
}
|
2010-11-16 22:24:49 -08:00
|
|
|
else
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->fd_handlers_with_prep = eina_list_remove_list
|
|
|
|
(pd->fd_handlers_with_prep, l);
|
2010-08-14 04:19:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-01 11:08:49 -07:00
|
|
|
#if !defined(USE_G_MAIN_LOOP)
|
2003-09-23 01:09:32 -07:00
|
|
|
static int
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2008-02-24 00:42:39 -08:00
|
|
|
struct timeval tv, *t;
|
2011-10-20 22:40:39 -07:00
|
|
|
fd_set rfds, wfds, exfds;
|
2012-08-01 07:37:24 -07:00
|
|
|
Ecore_Fd_Handler *fdh;
|
|
|
|
Eina_List *l;
|
2017-12-16 23:03:33 -08:00
|
|
|
int max_fd, ret;
|
|
|
|
#ifndef _WIN32
|
|
|
|
int err_no;
|
|
|
|
#endif
|
2009-03-04 02:50:14 -08:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
t = NULL;
|
2017-11-08 22:59:04 -08:00
|
|
|
if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0)))
|
|
|
|
{ // finite() tests for NaN, too big, too small, and infinity.
|
2010-09-29 23:09:20 -07:00
|
|
|
tv.tv_sec = 0;
|
|
|
|
tv.tv_usec = 0;
|
|
|
|
t = &tv;
|
2006-01-01 12:29:34 -08:00
|
|
|
}
|
|
|
|
else if (timeout > 0.0)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
int sec, usec;
|
2004-06-09 03:35:01 -07:00
|
|
|
|
|
|
|
#ifdef FIX_HZ
|
2010-09-29 23:09:20 -07:00
|
|
|
timeout += (0.5 / HZ);
|
|
|
|
sec = (int)timeout;
|
|
|
|
usec = (int)((timeout - (double)sec) * 1000000);
|
2007-08-26 04:17:21 -07:00
|
|
|
#else
|
2010-09-29 23:09:20 -07:00
|
|
|
sec = (int)timeout;
|
|
|
|
usec = (int)((timeout - (double)sec) * 1000000);
|
2007-08-26 04:17:21 -07:00
|
|
|
#endif
|
2010-09-29 23:09:20 -07:00
|
|
|
tv.tv_sec = sec;
|
|
|
|
tv.tv_usec = usec;
|
|
|
|
t = &tv;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
max_fd = 0;
|
|
|
|
FD_ZERO(&rfds);
|
|
|
|
FD_ZERO(&wfds);
|
2004-02-24 11:45:01 -08:00
|
|
|
FD_ZERO(&exfds);
|
2005-03-28 00:55:59 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// call the prepare callback for all handlers
|
|
|
|
if (pd->fd_handlers_with_prep) _ecore_main_prepare_handlers(obj, pd);
|
2011-07-06 03:54:30 -07:00
|
|
|
|
2018-02-20 22:38:30 -08:00
|
|
|
#ifdef HAVE_SYS_EPOLL_H
|
2017-11-08 22:59:04 -08:00
|
|
|
if (pd->epoll_fd < 0)
|
2010-05-18 01:01:06 -07:00
|
|
|
{
|
2017-04-21 20:20:06 -07:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
EINA_INLIST_FOREACH(pd->fd_handlers, fdh)
|
2010-05-18 01:01:06 -07:00
|
|
|
{
|
2011-07-06 03:54:30 -07:00
|
|
|
if (!fdh->delete_me)
|
2010-05-18 01:01:06 -07:00
|
|
|
{
|
2011-07-06 03:54:30 -07:00
|
|
|
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;
|
|
|
|
}
|
2010-05-18 01:01:06 -07:00
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
}
|
2018-02-20 22:38:30 -08:00
|
|
|
#ifdef HAVE_SYS_EPOLL_H
|
2011-07-06 03:54:30 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// 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;
|
2009-04-10 05:48:25 -07:00
|
|
|
|
2016-11-09 21:16:30 -08:00
|
|
|
eina_evlog("<RUN", NULL, 0.0, NULL);
|
2015-05-10 03:05:54 -07:00
|
|
|
eina_evlog("!SLEEP", NULL, 0.0, t ? "timeout" : "forever");
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
2017-12-16 23:03:33 -08:00
|
|
|
#ifndef _WIN32
|
2016-07-07 20:24:42 -07:00
|
|
|
err_no = errno;
|
2017-12-16 23:03:33 -08:00
|
|
|
#endif
|
2015-05-10 03:05:54 -07:00
|
|
|
eina_evlog("!WAKE", NULL, 0.0, NULL);
|
2016-11-09 21:16:30 -08:00
|
|
|
eina_evlog(">RUN", NULL, 0.0, NULL);
|
2011-07-06 03:54:30 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->loop_time = ecore_time_get();
|
2003-09-23 01:09:32 -07:00
|
|
|
if (ret < 0)
|
|
|
|
{
|
2009-11-23 15:09:48 -08:00
|
|
|
#ifndef _WIN32
|
2016-07-07 19:00:55 -07:00
|
|
|
if (err_no == EINTR) return -1;
|
2017-11-08 22:59:04 -08:00
|
|
|
else if (err_no == EBADF) _ecore_main_fd_handlers_bads_rem(obj, pd);
|
2009-06-23 23:14:07 -07:00
|
|
|
#endif
|
2009-03-04 02:50:14 -08:00
|
|
|
}
|
|
|
|
if (ret > 0)
|
|
|
|
{
|
2018-02-20 22:38:30 -08:00
|
|
|
#ifdef HAVE_SYS_EPOLL_H
|
2017-11-08 22:59:04 -08:00
|
|
|
if (pd->epoll_fd >= 0)
|
|
|
|
_ecore_main_fdh_epoll_mark_active(obj, pd);
|
2011-07-06 03:54:30 -07:00
|
|
|
else
|
2017-04-21 20:20:06 -07:00
|
|
|
#endif
|
2010-07-29 19:42:47 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
EINA_INLIST_FOREACH(pd->fd_handlers, fdh)
|
2010-07-29 19:42:47 -07:00
|
|
|
{
|
2011-07-06 03:54:30 -07:00
|
|
|
if (!fdh->delete_me)
|
|
|
|
{
|
|
|
|
if (FD_ISSET(fdh->fd, &rfds))
|
2017-11-08 22:59:04 -08:00
|
|
|
fdh->read_active = EINA_TRUE;
|
2011-07-06 03:54:30 -07:00
|
|
|
if (FD_ISSET(fdh->fd, &wfds))
|
|
|
|
fdh->write_active = EINA_TRUE;
|
|
|
|
if (FD_ISSET(fdh->fd, &exfds))
|
|
|
|
fdh->error_active = EINA_TRUE;
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_try_add_to_call_list(obj, pd, fdh);
|
2011-07-06 03:54:30 -07:00
|
|
|
}
|
2010-07-29 19:42:47 -07:00
|
|
|
}
|
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
EINA_LIST_FOREACH(pd->file_fd_handlers, l, fdh)
|
2012-08-12 19:54:57 -07:00
|
|
|
{
|
|
|
|
if (!fdh->delete_me)
|
|
|
|
{
|
|
|
|
if (FD_ISSET(fdh->fd, &rfds))
|
2017-11-08 22:59:04 -08:00
|
|
|
fdh->read_active = EINA_TRUE;
|
2012-08-12 19:54:57 -07:00
|
|
|
if (FD_ISSET(fdh->fd, &wfds))
|
|
|
|
fdh->write_active = EINA_TRUE;
|
|
|
|
if (FD_ISSET(fdh->fd, &exfds))
|
|
|
|
fdh->error_active = EINA_TRUE;
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_try_add_to_call_list(obj, pd, fdh);
|
2012-08-12 19:54:57 -07:00
|
|
|
}
|
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fd_handlers_cleanup(obj, pd);
|
2009-11-23 15:09:48 -08:00
|
|
|
#ifdef _WIN32
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_win32_handlers_cleanup(obj, pd);
|
2009-11-23 15:09:48 -08:00
|
|
|
#endif
|
2010-09-29 23:09:20 -07:00
|
|
|
return 1;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2011-06-01 23:08:59 -07:00
|
|
|
#endif
|
2003-09-23 01:09:32 -07:00
|
|
|
|
2009-11-23 15:09:48 -08:00
|
|
|
#ifndef _WIN32
|
2011-06-01 23:08:59 -07:00
|
|
|
# ifndef USE_G_MAIN_LOOP
|
2009-04-10 05:48:25 -07:00
|
|
|
static void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fd_handlers_bads_rem(Eo *obj, Efl_Loop_Data *pd)
|
2009-04-10 05:48:25 -07:00
|
|
|
{
|
|
|
|
Ecore_Fd_Handler *fdh;
|
|
|
|
Eina_Inlist *l;
|
2010-04-27 16:53:08 -07:00
|
|
|
int found = 0;
|
2009-04-10 05:48:25 -07:00
|
|
|
|
2010-04-26 21:30:55 -07:00
|
|
|
ERR("Removing bad fds");
|
2017-11-08 22:59:04 -08:00
|
|
|
for (l = EINA_INLIST_GET(pd->fd_handlers); l; )
|
2009-04-10 05:48:25 -07:00
|
|
|
{
|
2011-10-20 22:40:39 -07:00
|
|
|
fdh = (Ecore_Fd_Handler *)l;
|
2010-09-29 23:09:20 -07:00
|
|
|
l = l->next;
|
|
|
|
errno = 0;
|
|
|
|
|
|
|
|
if ((fcntl(fdh->fd, F_GETFD) < 0) && (errno == EBADF))
|
|
|
|
{
|
|
|
|
ERR("Found bad fd at index %d", fdh->fd);
|
|
|
|
if (fdh->flags & ECORE_FD_ERROR)
|
|
|
|
{
|
|
|
|
ERR("Fd set for error! calling user");
|
|
|
|
fdh->references++;
|
2011-08-11 03:59:48 -07:00
|
|
|
if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh))
|
2010-09-29 23:09:20 -07:00
|
|
|
{
|
|
|
|
ERR("Fd function err returned 0, remove it");
|
2010-11-18 11:56:26 -08:00
|
|
|
if (!fdh->delete_me)
|
|
|
|
{
|
2010-11-30 18:34:48 -08:00
|
|
|
fdh->delete_me = EINA_TRUE;
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fdh_poll_del(pd, fdh);
|
|
|
|
pd->fd_handlers_to_delete =
|
|
|
|
eina_list_append(pd->fd_handlers_to_delete, fdh);
|
2010-11-18 11:56:26 -08:00
|
|
|
}
|
2010-04-27 16:53:08 -07:00
|
|
|
found++;
|
2010-09-29 23:09:20 -07:00
|
|
|
}
|
|
|
|
fdh->references--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
ERR("Problematic fd found at %d! setting it for delete",
|
|
|
|
fdh->fd);
|
2010-11-18 11:56:26 -08:00
|
|
|
if (!fdh->delete_me)
|
|
|
|
{
|
2010-11-30 18:34:48 -08:00
|
|
|
fdh->delete_me = EINA_TRUE;
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fdh_poll_del(pd, fdh);
|
|
|
|
pd->fd_handlers_to_delete =
|
|
|
|
eina_list_append(pd->fd_handlers_to_delete, fdh);
|
2010-11-18 11:56:26 -08:00
|
|
|
}
|
|
|
|
|
2010-04-27 16:53:08 -07:00
|
|
|
found++;
|
2010-09-29 23:09:20 -07:00
|
|
|
}
|
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
}
|
2010-04-27 16:53:08 -07:00
|
|
|
if (found == 0)
|
|
|
|
{
|
2011-06-01 23:08:59 -07:00
|
|
|
# ifdef HAVE_GLIB
|
2010-04-27 17:05:56 -07:00
|
|
|
ERR("No bad fd found. Maybe a foreign fd from glib?");
|
2011-06-01 23:08:59 -07:00
|
|
|
# else
|
2010-04-27 17:05:56 -07:00
|
|
|
ERR("No bad fd found. EEEK!");
|
2011-06-01 23:08:59 -07:00
|
|
|
# endif
|
2010-04-27 16:53:08 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fd_handlers_cleanup(obj, pd);
|
2009-04-10 05:48:25 -07:00
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2011-06-01 23:08:59 -07:00
|
|
|
# endif
|
2009-11-23 15:09:48 -08:00
|
|
|
#endif
|
2009-04-10 05:48:25 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
static void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fd_handlers_cleanup(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2017-11-23 15:12:30 -08:00
|
|
|
Ecore_Fd_Handler *fdh, *last;
|
2010-11-17 23:23:14 -08:00
|
|
|
Eina_List *l, *l2;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2017-11-23 15:12:30 -08:00
|
|
|
// Cleanup deleted caller from the list
|
|
|
|
last = NULL;
|
2017-11-08 22:59:04 -08:00
|
|
|
fdh = pd->fd_handlers_to_call;
|
2017-11-23 15:12:30 -08:00
|
|
|
while (fdh)
|
|
|
|
{
|
|
|
|
if (fdh->delete_me)
|
|
|
|
{
|
|
|
|
if (!last)
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->fd_handlers_to_call = fdh == fdh->next_ready ?
|
|
|
|
NULL : fdh->next_ready;
|
2017-11-23 15:12:30 -08:00
|
|
|
else
|
2017-11-08 22:59:04 -08:00
|
|
|
last->next_ready = fdh == fdh->next_ready ?
|
|
|
|
last : fdh->next_ready;
|
2017-11-23 15:12:30 -08:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
else last = fdh;
|
2017-11-23 15:12:30 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (fdh == fdh->next_ready) break;
|
2017-11-23 15:12:30 -08:00
|
|
|
fdh = fdh->next_ready;
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (!pd->fd_handlers_to_delete) return;
|
|
|
|
EINA_LIST_FOREACH_SAFE(pd->fd_handlers_to_delete, l, l2, fdh)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2010-12-01 02:31:20 -08:00
|
|
|
if (!fdh)
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->fd_handlers_to_delete = eina_list_remove_list
|
|
|
|
(l, pd->fd_handlers_to_delete);
|
2010-12-01 02:31:20 -08:00
|
|
|
continue;
|
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
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));
|
2012-08-01 07:37:24 -07:00
|
|
|
if (fdh->file)
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->file_fd_handlers = eina_list_remove(pd->file_fd_handlers, fdh);
|
2010-11-17 23:23:14 -08:00
|
|
|
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
|
2011-12-02 19:39:07 -08:00
|
|
|
ecore_fd_handler_mp_free(fdh);
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->fd_handlers_to_delete = eina_list_remove_list
|
|
|
|
(pd->fd_handlers_to_delete, l);
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-23 15:09:48 -08:00
|
|
|
#ifdef _WIN32
|
|
|
|
static void
|
2017-12-16 23:27:08 -08:00
|
|
|
_ecore_main_win32_handlers_cleanup(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
|
2009-11-23 15:09:48 -08:00
|
|
|
{
|
|
|
|
Ecore_Win32_Handler *wh;
|
2017-11-08 22:59:04 -08:00
|
|
|
Eina_List *l, *l2;
|
2009-11-23 15:09:48 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (!pd->win32_handlers_to_delete) return;
|
|
|
|
EINA_LIST_FOREACH_SAFE(pd->win32_handlers_to_delete, l, l2, wh)
|
2009-11-23 15:09:48 -08:00
|
|
|
{
|
2015-09-24 22:32:32 -07:00
|
|
|
if (!wh)
|
2009-11-23 15:09:48 -08:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->win32_handlers_to_delete = eina_list_remove_list
|
|
|
|
(l, pd->win32_handlers_to_delete);
|
2015-09-24 22:32:32 -07:00
|
|
|
continue;
|
2009-11-23 15:09:48 -08:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
// 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));
|
2015-09-24 22:32:32 -07:00
|
|
|
ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
|
|
|
|
ecore_win32_handler_mp_free(wh);
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->win32_handlers_to_delete = eina_list_remove_list
|
|
|
|
(pd->win32_handlers_to_delete, l);
|
2009-11-23 15:09:48 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
static void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fd_handlers_call(Eo *obj, Efl_Loop_Data *pd)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// 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;
|
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (!pd->fd_handlers_to_call_current) return;
|
2015-05-10 03:05:54 -07:00
|
|
|
eina_evlog("+fd_handlers", NULL, 0.0, NULL);
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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--;
|
2017-02-10 09:58:24 -08:00
|
|
|
#ifdef EFL_EXTRA_SANITY_CHECKS
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_fd_valid(obj, pd);
|
2017-02-10 09:58:24 -08:00
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
fdh->read_active = EINA_FALSE;
|
|
|
|
fdh->write_active = EINA_FALSE;
|
|
|
|
fdh->error_active = EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// stop when we point to ourselves
|
|
|
|
if (fdh->next_ready == fdh)
|
|
|
|
{
|
|
|
|
fdh->next_ready = NULL;
|
|
|
|
pd->fd_handlers_to_call_current = NULL;
|
|
|
|
break;
|
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->fd_handlers_to_call_current = fdh->next_ready;
|
|
|
|
fdh->next_ready = NULL;
|
2011-10-20 22:40:39 -07:00
|
|
|
}
|
2015-05-10 03:05:54 -07:00
|
|
|
eina_evlog("-fd_handlers", NULL, 0.0, NULL);
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fd_handlers_buf_call(Eo *obj, Efl_Loop_Data *pd)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2009-03-04 02:50:14 -08:00
|
|
|
Ecore_Fd_Handler *fdh;
|
2010-11-16 22:50:52 -08:00
|
|
|
Eina_List *l, *l2;
|
2003-09-23 01:09:32 -07:00
|
|
|
int ret;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (!pd->fd_handlers_with_buffer) return 0;
|
2015-05-10 03:05:54 -07:00
|
|
|
eina_evlog("+fd_handlers_buf", NULL, 0.0, NULL);
|
2003-09-23 01:09:32 -07:00
|
|
|
ret = 0;
|
2017-11-08 22:59:04 -08:00
|
|
|
EINA_LIST_FOREACH_SAFE(pd->fd_handlers_with_buffer, l, l2, fdh)
|
2010-05-18 01:01:06 -07:00
|
|
|
{
|
2010-12-01 02:31:20 -08:00
|
|
|
if (!fdh)
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->fd_handlers_with_buffer = eina_list_remove_list
|
|
|
|
(l, pd->fd_handlers_with_buffer);
|
2010-12-01 02:31:20 -08:00
|
|
|
continue;
|
|
|
|
}
|
2010-11-16 22:50:52 -08:00
|
|
|
if ((!fdh->delete_me) && fdh->buf_func)
|
2010-05-18 01:01:06 -07:00
|
|
|
{
|
2010-11-16 22:50:52 -08:00
|
|
|
fdh->references++;
|
2011-08-11 03:59:48 -07:00
|
|
|
if (_ecore_call_fd_cb(fdh->buf_func, fdh->buf_data, fdh))
|
2010-05-18 01:01:06 -07:00
|
|
|
{
|
2011-08-11 03:59:48 -07:00
|
|
|
ret |= _ecore_call_fd_cb(fdh->func, fdh->data, fdh);
|
2011-01-28 21:34:00 -08:00
|
|
|
fdh->read_active = EINA_TRUE;
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_try_add_to_call_list(obj, pd, fdh);
|
2010-05-18 01:01:06 -07:00
|
|
|
}
|
2010-11-16 22:50:52 -08:00
|
|
|
fdh->references--;
|
2010-05-18 01:01:06 -07:00
|
|
|
}
|
2010-11-16 22:50:52 -08:00
|
|
|
else
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->fd_handlers_with_buffer = eina_list_remove_list
|
|
|
|
(pd->fd_handlers_with_buffer, l);
|
2010-05-18 01:01:06 -07:00
|
|
|
}
|
2015-05-10 03:05:54 -07:00
|
|
|
eina_evlog("-fd_handlers_buf", NULL, 0.0, NULL);
|
2003-09-23 01:09:32 -07:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-09-01 11:08:49 -07:00
|
|
|
#ifdef HAVE_LIBUV
|
|
|
|
static void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_loop_uv_prepare(uv_prepare_t *handle EINA_UNUSED)
|
2014-09-01 11:08:49 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Eo *obj = ML_OBJ;
|
|
|
|
Efl_Loop_Data *pd = ML_DAT;
|
|
|
|
double t = -1;
|
|
|
|
|
2014-09-01 11:08:49 -07:00
|
|
|
_dl_uv_timer_stop(&_ecore_main_uv_handle_timers);
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
2016-01-14 14:52:37 -08:00
|
|
|
|
2014-09-01 11:08:49 -07:00
|
|
|
in_main_loop++;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop = in_main_loop;
|
2016-01-14 14:52:37 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (!_ecore_main_uv_idling)
|
2014-09-01 11:08:49 -07:00
|
|
|
{
|
|
|
|
_ecore_main_uv_idling = EINA_TRUE;
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_ENTER, NULL);
|
2014-09-01 11:08:49 -07:00
|
|
|
_ecore_throttle();
|
2017-11-08 22:59:04 -08:00
|
|
|
_throttle_do(pd);
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (_ecore_main_uv_idling)
|
2014-09-01 11:08:49 -07:00
|
|
|
{
|
2017-12-21 02:31:24 -08:00
|
|
|
_ecore_main_idler_all_call(obj);
|
2017-11-08 22:59:04 -08:00
|
|
|
DBG("called idles");
|
2017-12-21 02:31:24 -08:00
|
|
|
if (_ecore_main_idlers_exist(pd) || (pd->message_queue)) t = 0.0;
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (pd->do_quit)
|
2014-09-01 11:08:49 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
DBG("do quit outside loop");
|
2016-01-14 14:52:37 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (_ecore_main_uv_idling)
|
|
|
|
{
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
|
2017-11-08 22:59:04 -08:00
|
|
|
_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;
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
assert(!pd->fd_handlers_to_call);
|
2014-09-01 11:08:49 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->loop_time = ecore_time_get();
|
|
|
|
_efl_loop_timer_enable_new(obj, pd);
|
|
|
|
if (_efl_loop_timers_exists(obj, pd) || (t >= 0))
|
2014-09-01 11:08:49 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
double tnext = _efl_loop_timer_next_get(obj, pd);
|
2014-09-01 11:08:49 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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");
|
2014-09-01 11:08:49 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
done:
|
|
|
|
if (pd->fd_handlers_with_prep) _ecore_main_prepare_handlers(obj, pd);
|
2014-09-01 11:08:49 -07:00
|
|
|
in_main_loop--;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop = in_main_loop;
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
|
|
|
#endif
|
2011-09-01 20:29:11 -07:00
|
|
|
|
2014-09-01 11:08:49 -07:00
|
|
|
#if !defined(USE_G_MAIN_LOOP)
|
2011-09-01 20:29:11 -07:00
|
|
|
enum {
|
|
|
|
SPIN_MORE,
|
|
|
|
SPIN_RESTART,
|
|
|
|
LOOP_CONTINUE
|
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
2017-11-08 22:59:04 -08:00
|
|
|
_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
|
2017-12-21 02:31:24 -08:00
|
|
|
_ecore_main_idler_all_call(obj);
|
2017-11-08 22:59:04 -08:00
|
|
|
// which returns false if no more idelrs exist
|
2017-12-21 02:31:24 -08:00
|
|
|
if (!_ecore_main_idlers_exist(pd)) return SPIN_RESTART;
|
2017-11-08 22:59:04 -08:00
|
|
|
// sneaky - drop through or if checks - the first one to succeed
|
|
|
|
// drops through and returns "continue" so further ones dont run
|
2017-12-21 02:31:24 -08:00
|
|
|
if ((_ecore_main_select(obj, pd, 0.0) > 0) || (pd->message_queue) ||
|
2017-11-08 22:59:04 -08:00
|
|
|
(_ecore_signal_count_get(obj, pd) > 0) || (pd->do_quit))
|
|
|
|
return LOOP_CONTINUE;
|
|
|
|
// default - spin more
|
|
|
|
return SPIN_MORE;
|
2011-09-01 20:29:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-11-08 22:59:04 -08:00
|
|
|
_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;
|
2011-09-01 20:29:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-11-08 22:59:04 -08:00
|
|
|
_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;
|
2011-09-01 20:29:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_fps_marker_1(void)
|
|
|
|
{
|
|
|
|
if (!_ecore_fps_debug) return;
|
|
|
|
t2 = ecore_time_get();
|
|
|
|
if ((t1 > 0.0) && (t2 > 0.0)) _ecore_fps_debug_runtime_add(t2 - t1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_fps_marker_2(void)
|
|
|
|
{
|
|
|
|
if (!_ecore_fps_debug) return;
|
|
|
|
t1 = ecore_time_get();
|
|
|
|
}
|
|
|
|
|
2007-11-21 04:16:16 -08:00
|
|
|
static void
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_loop_iterate_internal(Eo *obj, Efl_Loop_Data *pd, int once_only)
|
2007-11-21 04:16:16 -08:00
|
|
|
{
|
2009-02-24 09:26:26 -08:00
|
|
|
double next_time = -1.0;
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (obj == ML_OBJ)
|
|
|
|
{
|
|
|
|
in_main_loop++;
|
|
|
|
pd->in_loop = in_main_loop;
|
|
|
|
}
|
|
|
|
// 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
|
2017-12-21 02:31:24 -08:00
|
|
|
if (pd->message_queue)
|
2017-11-08 22:59:04 -08:00
|
|
|
{
|
|
|
|
// but first conceptually enter an idle state
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_ENTER, NULL);
|
2012-02-01 21:21:24 -08:00
|
|
|
_ecore_throttle();
|
2017-11-08 22:59:04 -08:00
|
|
|
_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
|
2012-02-01 21:21:24 -08:00
|
|
|
goto process_all;
|
2011-06-28 05:34:52 -07:00
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2011-09-01 20:29:11 -07:00
|
|
|
if (once_only)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// 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))
|
2012-02-01 21:21:24 -08:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
_efl_loop_timer_enable_new(obj, pd);
|
2012-02-01 21:21:24 -08:00
|
|
|
goto process_all;
|
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2011-09-01 20:29:11 -07:00
|
|
|
else
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// call idle enterers ...
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_ENTER, NULL);
|
2012-02-01 21:21:24 -08:00
|
|
|
_ecore_throttle();
|
2017-11-08 22:59:04 -08:00
|
|
|
_throttle_do(pd);
|
2011-09-01 20:29:11 -07:00
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// 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);
|
2008-06-09 05:15:34 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// if there are any (buffered fd handling may generate them)
|
|
|
|
// then jump to processing them */
|
2017-12-21 02:31:24 -08:00
|
|
|
if (pd->message_queue)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_select(obj, pd, 0.0);
|
|
|
|
_efl_loop_timer_enable_new(obj, pd);
|
2011-09-01 20:29:11 -07:00
|
|
|
goto process_all;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
if (once_only)
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// in once_only mode enter idle here instead and then return
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_ENTER, NULL);
|
2012-02-01 21:21:24 -08:00
|
|
|
_ecore_throttle();
|
2017-11-08 22:59:04 -08:00
|
|
|
_throttle_do(pd);
|
|
|
|
_efl_loop_timer_enable_new(obj, pd);
|
2012-02-01 21:21:24 -08:00
|
|
|
goto done;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2007-08-26 04:17:21 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (obj == ML_OBJ) _ecore_fps_marker_1();
|
|
|
|
|
|
|
|
// start of the sleeping or looping section
|
|
|
|
start_loop: //-*************************************************************
|
|
|
|
// 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);
|
2011-09-01 20:29:11 -07:00
|
|
|
goto done;
|
2004-05-12 20:20:13 -07:00
|
|
|
}
|
2017-12-21 02:31:24 -08:00
|
|
|
if (!pd->message_queue)
|
2003-09-23 01:09:32 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// init flags
|
|
|
|
next_time = _efl_loop_timer_next_get(obj, pd);
|
|
|
|
// no idlers
|
2017-12-21 02:31:24 -08:00
|
|
|
if (!_ecore_main_idlers_exist(pd))
|
2012-02-01 21:21:24 -08:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// sleep until timeout or forever (-1.0) waiting for on fds
|
|
|
|
_ecore_main_select(obj, pd, next_time);
|
2012-02-01 21:21:24 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int action = LOOP_CONTINUE;
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// no timers - spin
|
|
|
|
if (next_time < 0) action = _ecore_main_loop_spin_no_timers(obj, pd);
|
2017-12-14 21:36:30 -08:00
|
|
|
// timers - spin
|
2017-11-08 22:59:04 -08:00
|
|
|
else action = _ecore_main_loop_spin_timers(obj, pd);
|
2012-02-01 21:21:24 -08:00
|
|
|
if (action == SPIN_RESTART) goto start_loop;
|
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
if (obj == ML_OBJ) _ecore_fps_marker_2();
|
2011-09-01 20:29:11 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// actually wake up and deal with input, events etc.
|
|
|
|
process_all: //-*********************************************************
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// we came out of our "wait state" so idle has exited
|
2013-12-07 22:05:51 -08:00
|
|
|
if (!once_only)
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_animator_run_reset(); // XXX:
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
// 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 ...
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_loop_message_process(obj);
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_fd_handlers_cleanup(obj, pd);
|
2008-11-17 22:56:31 -08:00
|
|
|
|
2011-06-28 05:34:52 -07:00
|
|
|
if (once_only)
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
// if in once_only mode handle idle exiting
|
2017-12-21 02:31:24 -08:00
|
|
|
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_ENTER, NULL);
|
2012-02-01 21:21:24 -08:00
|
|
|
_ecore_throttle();
|
2017-11-08 22:59:04 -08:00
|
|
|
_throttle_do(pd);
|
2011-06-28 05:34:52 -07:00
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
done: //-*****************************************************************
|
|
|
|
// Agressively flush animator
|
2016-07-13 15:09:03 -07:00
|
|
|
_ecore_animator_flush();
|
2017-01-10 22:34:15 -08:00
|
|
|
if (!once_only)
|
2017-11-08 22:59:04 -08:00
|
|
|
eina_slstr_local_clear(); // Free all short lived strings
|
|
|
|
|
|
|
|
if (obj == ML_OBJ)
|
2017-01-10 22:34:15 -08:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
in_main_loop--;
|
|
|
|
pd->in_loop = in_main_loop;
|
2017-01-10 22:34:15 -08:00
|
|
|
}
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|
2010-08-14 04:19:03 -07:00
|
|
|
#endif
|
2009-06-23 23:14:07 -07:00
|
|
|
|
|
|
|
#ifdef _WIN32
|
2014-06-22 08:33:34 -07:00
|
|
|
typedef struct
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
DWORD objects_nbr;
|
2014-06-22 08:33:34 -07:00
|
|
|
HANDLE *objects;
|
2017-11-08 22:59:04 -08:00
|
|
|
DWORD timeout;
|
2014-06-22 08:33:34 -07:00
|
|
|
} Ecore_Main_Win32_Thread_Data;
|
|
|
|
|
|
|
|
static unsigned int __stdcall
|
|
|
|
_ecore_main_win32_objects_wait_thread(void *data)
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
2014-06-22 08:33:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static DWORD
|
|
|
|
_ecore_main_win32_objects_wait(DWORD objects_nbr,
|
|
|
|
const HANDLE *objects,
|
|
|
|
DWORD timeout)
|
|
|
|
{
|
|
|
|
Ecore_Main_Win32_Thread_Data *threads_data;
|
|
|
|
HANDLE *threads_handles;
|
2017-12-16 22:07:37 -08:00
|
|
|
DWORD threads_nbr, threads_remain, objects_idx, result, i;
|
2014-06-22 08:33:34 -07:00
|
|
|
|
|
|
|
if (objects_nbr < MAXIMUM_WAIT_OBJECTS)
|
|
|
|
return MsgWaitForMultipleObjects(objects_nbr,
|
|
|
|
objects,
|
|
|
|
EINA_FALSE,
|
|
|
|
timeout, QS_ALLINPUT);
|
2017-11-08 22:59:04 -08:00
|
|
|
// too much objects, so we launch a bunch of threads to
|
|
|
|
// wait for, each one calls MsgWaitForMultipleObjects
|
2014-06-22 08:33:34 -07:00
|
|
|
|
|
|
|
threads_nbr = objects_nbr / (MAXIMUM_WAIT_OBJECTS - 1);
|
|
|
|
threads_remain = objects_nbr % (MAXIMUM_WAIT_OBJECTS - 1);
|
2017-11-08 22:59:04 -08:00
|
|
|
if (threads_remain > 0) threads_nbr++;
|
2014-06-22 08:33:34 -07:00
|
|
|
|
|
|
|
if (threads_nbr > MAXIMUM_WAIT_OBJECTS)
|
|
|
|
{
|
|
|
|
CRI("Too much objects to wait for (%lu).", objects_nbr);
|
|
|
|
return WAIT_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
threads_handles = (HANDLE *)malloc(threads_nbr * sizeof(HANDLE));
|
|
|
|
if (!threads_handles)
|
|
|
|
{
|
|
|
|
ERR("Can not allocate memory for the waiting thread.");
|
|
|
|
return WAIT_FAILED;
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
threads_data = (Ecore_Main_Win32_Thread_Data *)
|
|
|
|
malloc(threads_nbr * sizeof(Ecore_Main_Win32_Thread_Data));
|
2014-06-22 08:33:34 -07:00
|
|
|
if (!threads_data)
|
|
|
|
{
|
|
|
|
ERR("Can not allocate memory for the waiting thread.");
|
|
|
|
goto free_threads_handles;
|
|
|
|
}
|
|
|
|
|
|
|
|
objects_idx = 0;
|
|
|
|
for (i = 0; i < threads_nbr; i++)
|
|
|
|
{
|
|
|
|
threads_data[i].timeout = timeout;
|
|
|
|
threads_data[i].objects = (HANDLE *)objects + objects_idx;
|
|
|
|
|
|
|
|
if ((i == (threads_nbr - 1)) && (threads_remain != 0))
|
|
|
|
{
|
|
|
|
threads_data[i].objects_nbr = threads_remain;
|
|
|
|
objects_idx += threads_remain;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
threads_data[i].objects_nbr = (MAXIMUM_WAIT_OBJECTS - 1);
|
|
|
|
objects_idx += (MAXIMUM_WAIT_OBJECTS - 1);
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
threads_handles[i] = (HANDLE)_beginthreadex
|
|
|
|
(NULL, 0, _ecore_main_win32_objects_wait_thread,
|
|
|
|
&threads_data[i], 0, NULL);
|
2014-06-22 08:33:34 -07:00
|
|
|
if (!threads_handles[i])
|
|
|
|
{
|
|
|
|
DWORD j;
|
|
|
|
|
|
|
|
ERR("Can not create the waiting threads.");
|
|
|
|
WaitForMultipleObjects(i, threads_handles, TRUE, INFINITE);
|
|
|
|
for (j = 0; j < i; j++)
|
|
|
|
CloseHandle(threads_handles[i]);
|
|
|
|
|
|
|
|
goto free_threads_data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result = WaitForMultipleObjects(threads_nbr,
|
|
|
|
threads_handles,
|
2017-11-08 22:59:04 -08:00
|
|
|
FALSE, // we wait until one thread signaled
|
2014-06-22 08:33:34 -07:00
|
|
|
INFINITE);
|
|
|
|
|
|
|
|
if (result < (WAIT_OBJECT_0 + threads_nbr))
|
|
|
|
{
|
|
|
|
DWORD wait_res;
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// One of the thread callback has exited so we retrieve
|
|
|
|
// its exit status, that is the returned value of
|
|
|
|
// MsgWaitForMultipleObjects()
|
2014-06-22 08:33:34 -07:00
|
|
|
if (GetExitCodeThread(threads_handles[result - WAIT_OBJECT_0],
|
|
|
|
&wait_res))
|
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
WaitForMultipleObjects(threads_nbr, threads_handles,
|
|
|
|
TRUE, INFINITE);
|
2014-06-22 08:33:34 -07:00
|
|
|
for (i = 0; i < threads_nbr; i++)
|
|
|
|
CloseHandle(threads_handles[i]);
|
|
|
|
free(threads_data);
|
|
|
|
free(threads_handles);
|
|
|
|
return wait_res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("Error when waiting threads.");
|
|
|
|
if (result == WAIT_FAILED)
|
2017-12-10 22:06:02 -08:00
|
|
|
ERR("%s", evil_last_error_get());
|
2014-06-22 08:33:34 -07:00
|
|
|
goto close_thread;
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
close_thread:
|
2014-06-22 08:33:34 -07:00
|
|
|
WaitForMultipleObjects(threads_nbr, threads_handles, TRUE, INFINITE);
|
2017-11-08 22:59:04 -08:00
|
|
|
for (i = 0; i < threads_nbr; i++) CloseHandle(threads_handles[i]);
|
|
|
|
free_threads_data:
|
2014-06-22 08:33:34 -07:00
|
|
|
free(threads_data);
|
2017-11-08 22:59:04 -08:00
|
|
|
free_threads_handles:
|
2014-06-22 08:33:34 -07:00
|
|
|
free(threads_handles);
|
|
|
|
|
|
|
|
return WAIT_FAILED;
|
|
|
|
}
|
|
|
|
|
2016-12-21 05:08:58 -08:00
|
|
|
static unsigned int
|
|
|
|
_stdin_wait_thread(void *data EINA_UNUSED)
|
|
|
|
{
|
|
|
|
int c = getc(stdin);
|
|
|
|
ungetc(c, stdin);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-06-23 23:14:07 -07:00
|
|
|
static int
|
2012-11-25 01:55:32 -08:00
|
|
|
_ecore_main_win32_select(int nfds EINA_UNUSED,
|
2011-10-20 22:40:39 -07:00
|
|
|
fd_set *readfds,
|
|
|
|
fd_set *writefds,
|
|
|
|
fd_set *exceptfds,
|
|
|
|
struct timeval *tv)
|
2009-06-23 23:14:07 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
Efl_Loop_Data *pd = ML_DAT;
|
2014-06-22 08:33:34 -07:00
|
|
|
HANDLE *objects;
|
|
|
|
int *sockets;
|
2010-05-13 01:10:17 -07:00
|
|
|
Ecore_Fd_Handler *fdh;
|
2009-10-25 00:07:48 -07:00
|
|
|
Ecore_Win32_Handler *wh;
|
2017-11-08 22:59:04 -08:00
|
|
|
static HANDLE stdin_wait_thread = INVALID_HANDLE_VALUE;
|
|
|
|
HANDLE stdin_handle;
|
|
|
|
DWORD result, timeout;
|
|
|
|
MSG msg;
|
2014-06-22 08:33:34 -07:00
|
|
|
unsigned int fds_nbr = 0;
|
2009-11-23 15:09:48 -08:00
|
|
|
unsigned int objects_nbr = 0;
|
|
|
|
unsigned int events_nbr = 0;
|
2010-05-18 01:01:06 -07:00
|
|
|
unsigned int i;
|
2011-10-20 22:40:39 -07:00
|
|
|
int res;
|
2017-11-08 22:59:04 -08:00
|
|
|
Eina_Bool stdin_thread_done = EINA_FALSE;
|
2009-06-23 23:14:07 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
fds_nbr = eina_inlist_count(EINA_INLIST_GET(pd->fd_handlers));
|
2014-06-22 08:33:34 -07:00
|
|
|
sockets = (int *)malloc(fds_nbr * sizeof(int));
|
2017-11-08 22:59:04 -08:00
|
|
|
if (!sockets) return -1;
|
2014-06-22 08:33:34 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
objects = (HANDLE)malloc((fds_nbr +
|
|
|
|
eina_inlist_count
|
|
|
|
(EINA_INLIST_GET(pd->win32_handlers)))
|
|
|
|
* sizeof(HANDLE));
|
2014-06-22 08:33:34 -07:00
|
|
|
if (!objects)
|
|
|
|
{
|
|
|
|
free(sockets);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// Create an event object per socket
|
|
|
|
EINA_INLIST_FOREACH(pd->fd_handlers, fdh)
|
2009-06-23 23:14:07 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
if (fdh->delete_me) continue;
|
2016-12-27 05:52:30 -08:00
|
|
|
|
2009-06-23 23:14:07 -07:00
|
|
|
WSAEVENT event;
|
|
|
|
long network_event;
|
|
|
|
|
|
|
|
network_event = 0;
|
2012-08-13 03:32:20 -07:00
|
|
|
if (readfds)
|
|
|
|
{
|
|
|
|
if (FD_ISSET(fdh->fd, readfds))
|
2015-01-30 05:25:53 -08:00
|
|
|
network_event |= FD_READ | FD_CONNECT | FD_ACCEPT;
|
2012-08-13 03:32:20 -07:00
|
|
|
}
|
|
|
|
if (writefds)
|
|
|
|
{
|
|
|
|
if (FD_ISSET(fdh->fd, writefds))
|
2015-01-30 05:25:53 -08:00
|
|
|
network_event |= FD_WRITE | FD_CLOSE;
|
2012-08-13 03:32:20 -07:00
|
|
|
}
|
|
|
|
if (exceptfds)
|
|
|
|
{
|
|
|
|
if (FD_ISSET(fdh->fd, exceptfds))
|
|
|
|
network_event |= FD_OOB;
|
|
|
|
}
|
2009-06-23 23:14:07 -07:00
|
|
|
|
2010-05-18 01:01:06 -07:00
|
|
|
if (network_event)
|
2010-09-29 23:09:20 -07:00
|
|
|
{
|
2009-06-23 23:14:07 -07:00
|
|
|
event = WSACreateEvent();
|
2010-09-29 23:09:20 -07:00
|
|
|
WSAEventSelect(fdh->fd, event, network_event);
|
|
|
|
objects[objects_nbr] = event;
|
|
|
|
sockets[events_nbr] = fdh->fd;
|
|
|
|
events_nbr++;
|
2009-10-25 00:07:48 -07:00
|
|
|
objects_nbr++;
|
2009-06-23 23:14:07 -07:00
|
|
|
}
|
|
|
|
}
|
2016-12-21 05:08:58 -08:00
|
|
|
stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
|
2017-11-08 22:59:04 -08:00
|
|
|
// store the HANDLEs in the objects to wait for
|
|
|
|
EINA_INLIST_FOREACH(pd->win32_handlers, wh)
|
2009-10-25 00:07:48 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
if (wh->delete_me) continue;
|
2016-12-27 05:52:30 -08:00
|
|
|
|
2016-12-21 05:08:58 -08:00
|
|
|
if (wh->h == stdin_handle)
|
|
|
|
{
|
|
|
|
if (stdin_wait_thread == INVALID_HANDLE_VALUE)
|
|
|
|
stdin_wait_thread = (HANDLE)_beginthreadex(NULL,
|
|
|
|
0,
|
|
|
|
_stdin_wait_thread,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
objects[objects_nbr] = stdin_wait_thread;
|
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
else objects[objects_nbr] = wh->h;
|
2009-10-25 00:07:48 -07:00
|
|
|
objects_nbr++;
|
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// Empty the queue before waiting
|
2009-06-23 23:14:07 -07:00
|
|
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
2009-06-23 23:14:07 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
// 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));
|
2009-06-23 23:14:07 -07:00
|
|
|
|
2014-06-22 08:33:34 -07:00
|
|
|
if (timeout == 0)
|
|
|
|
{
|
2016-07-13 05:01:50 -07:00
|
|
|
res = 0;
|
|
|
|
goto err;
|
2014-06-22 08:33:34 -07:00
|
|
|
}
|
2009-11-08 14:14:48 -08:00
|
|
|
|
2014-06-22 08:33:34 -07:00
|
|
|
result = _ecore_main_win32_objects_wait(objects_nbr,
|
|
|
|
(const HANDLE *)objects,
|
|
|
|
timeout);
|
2017-11-08 22:59:04 -08:00
|
|
|
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.
|
2009-11-08 14:14:48 -08:00
|
|
|
if (result == WAIT_FAILED)
|
|
|
|
{
|
2017-12-10 22:06:02 -08:00
|
|
|
WRN("%s", evil_last_error_get());
|
2009-11-23 15:09:48 -08:00
|
|
|
res = -1;
|
2009-11-08 14:14:48 -08:00
|
|
|
}
|
|
|
|
else if (result == WAIT_TIMEOUT)
|
2009-06-23 23:14:07 -07:00
|
|
|
{
|
2014-06-22 08:33:34 -07:00
|
|
|
INF("time-out interval elapsed.");
|
|
|
|
res = 0;
|
2009-06-23 23:14:07 -07:00
|
|
|
}
|
2009-10-25 00:07:48 -07:00
|
|
|
else if (result == (WAIT_OBJECT_0 + objects_nbr))
|
2009-06-23 23:14:07 -07:00
|
|
|
{
|
|
|
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
2010-09-29 23:09:20 -07:00
|
|
|
{
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
}
|
2009-06-23 23:14:07 -07:00
|
|
|
res = 0;
|
|
|
|
}
|
2014-01-08 05:44:22 -08:00
|
|
|
else if (result < WAIT_OBJECT_0 + events_nbr)
|
2009-06-23 23:14:07 -07:00
|
|
|
{
|
|
|
|
WSANETWORKEVENTS network_event;
|
|
|
|
|
2009-10-25 00:07:48 -07:00
|
|
|
WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
|
2017-11-08 22:59:04 -08:00
|
|
|
if ((network_event.lNetworkEvents &
|
|
|
|
(FD_READ | FD_CONNECT | FD_ACCEPT)) && readfds)
|
2011-10-20 22:40:39 -07:00
|
|
|
FD_SET(sockets[result], readfds);
|
2017-11-08 22:59:04 -08:00
|
|
|
if ((network_event.lNetworkEvents &
|
|
|
|
(FD_WRITE | FD_CLOSE)) && writefds)
|
2011-10-20 22:40:39 -07:00
|
|
|
FD_SET(sockets[result], writefds);
|
2012-08-13 03:32:20 -07:00
|
|
|
if ((network_event.lNetworkEvents & FD_OOB) && exceptfds)
|
2011-10-20 22:40:39 -07:00
|
|
|
FD_SET(sockets[result], exceptfds);
|
2009-06-23 23:14:07 -07:00
|
|
|
res = 1;
|
|
|
|
}
|
2011-01-07 00:18:19 -08:00
|
|
|
else if ((result >= (WAIT_OBJECT_0 + events_nbr)) &&
|
2010-05-18 01:01:06 -07:00
|
|
|
(result < (WAIT_OBJECT_0 + objects_nbr)))
|
2009-10-25 00:07:48 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
if (!pd->win32_handler_current)
|
|
|
|
// regular main loop, start from head
|
|
|
|
pd->win32_handler_current = pd->win32_handlers;
|
2010-09-29 23:09:20 -07:00
|
|
|
else
|
2017-11-08 22:59:04 -08:00
|
|
|
// recursive main loop, continue from where we were
|
|
|
|
pd->win32_handler_current = (Ecore_Win32_Handler *)
|
|
|
|
EINA_INLIST_GET(pd->win32_handler_current)->next;
|
2010-09-29 23:09:20 -07:00
|
|
|
|
2016-12-21 05:08:58 -08:00
|
|
|
if (objects[result - WAIT_OBJECT_0] == stdin_wait_thread)
|
|
|
|
stdin_thread_done = EINA_TRUE;
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
while (pd->win32_handler_current)
|
2010-09-29 23:09:20 -07:00
|
|
|
{
|
2017-11-08 22:59:04 -08:00
|
|
|
wh = pd->win32_handler_current;
|
2011-01-07 00:18:19 -08:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if ((objects[result - WAIT_OBJECT_0] == wh->h) ||
|
|
|
|
((objects[result - WAIT_OBJECT_0] == stdin_wait_thread) &&
|
|
|
|
(wh->h == stdin_handle)))
|
2010-05-18 01:01:06 -07:00
|
|
|
{
|
|
|
|
if (!wh->delete_me)
|
|
|
|
{
|
|
|
|
wh->references++;
|
|
|
|
if (!wh->func(wh->data, wh))
|
|
|
|
{
|
2010-11-30 18:34:48 -08:00
|
|
|
wh->delete_me = EINA_TRUE;
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->win32_handlers_to_delete = eina_list_append
|
|
|
|
(pd->win32_handlers_to_delete, wh);
|
2010-05-18 01:01:06 -07:00
|
|
|
}
|
|
|
|
wh->references--;
|
|
|
|
}
|
|
|
|
}
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2009-10-25 00:07:48 -07:00
|
|
|
}
|
|
|
|
res = 1;
|
|
|
|
}
|
2009-06-23 23:14:07 -07:00
|
|
|
else
|
|
|
|
{
|
2010-04-05 01:26:48 -07:00
|
|
|
ERR("unknown result...\n");
|
2009-11-23 15:09:48 -08:00
|
|
|
res = -1;
|
2009-06-23 23:14:07 -07:00
|
|
|
}
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
err:
|
|
|
|
// Remove event objects again
|
2010-05-18 01:01:06 -07:00
|
|
|
for (i = 0; i < events_nbr; i++) WSACloseEvent(objects[i]);
|
2009-10-25 00:07:48 -07:00
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
if (stdin_thread_done) stdin_wait_thread = INVALID_HANDLE_VALUE;
|
2016-12-21 05:08:58 -08:00
|
|
|
|
2014-06-22 08:33:34 -07:00
|
|
|
free(objects);
|
|
|
|
free(sockets);
|
2009-06-23 23:14:07 -07:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
#endif
|