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
|
|
|
|
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
|
2019-05-17 03:52:41 -07:00
|
|
|
# include <evil_private.h> /* evil_last_error_get */
|
2009-04-11 06:46:09 -07:00
|
|
|
#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
|
|
|
|
|
2020-05-21 09:58:46 -07:00
|
|
|
static double _ecore_main_loop_wakeup_time = 0.0;
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API double _ecore_main_loop_wakeup_time_get(void)
|
2020-05-21 09:58:46 -07:00
|
|
|
{
|
|
|
|
return _ecore_main_loop_wakeup_time;
|
|
|
|
}
|
|
|
|
|
2018-08-14 14:09:32 -07:00
|
|
|
static inline void
|
|
|
|
_update_loop_time(Efl_Loop_Data *pd)
|
|
|
|
{
|
|
|
|
double loop_time = ecore_time_get();
|
|
|
|
if (loop_time > pd->loop_time)
|
|
|
|
pd->loop_time = loop_time;
|
2020-05-21 09:58:46 -07:00
|
|
|
_ecore_main_loop_wakeup_time = loop_time;
|
2018-08-14 14:09:32 -07:00
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
2018-07-26 13:37:00 -07:00
|
|
|
if (fdh->read_active || fdh->write_active || fdh->error_active || (fdh->flags & ECORE_FD_ALWAYS))
|
2012-08-12 19:55:41 -07:00
|
|
|
{
|
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)
|
|
|
|
{
|
2018-09-20 22:46:50 -07:00
|
|
|
if (pd->throttle == 0) return;
|
2017-11-08 22:59:04 -08:00
|
|
|
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
|
|
|
|
|
2020-02-28 10:47:50 -08:00
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_main_pre_idle_exit(void)
|
|
|
|
{
|
|
|
|
// even if we never go idle, keep up flushing some of our freeq away
|
|
|
|
// on every idle exit which may happen if we even never called idlers
|
|
|
|
// for now an idea but dont enforce
|
2021-01-03 07:38:46 -08:00
|
|
|
eina_freeq_reduce(eina_freeq_main_get(), 128);
|
2020-02-28 10:47:50 -08:00
|
|
|
}
|
|
|
|
|
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;
|
2019-07-28 03:51:15 -07:00
|
|
|
eina_file_statgen_next();
|
2020-02-28 10:47:50 -08:00
|
|
|
_ecore_main_pre_idle_exit();
|
2017-12-21 02:31:24 -08:00
|
|
|
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
|
2019-10-14 06:30:03 -07:00
|
|
|
_ecore_main_idler_all_call(Eo *loop, Efl_Loop_Data *pd)
|
2017-12-21 02:31:24 -08:00
|
|
|
{
|
2019-10-14 06:30:03 -07:00
|
|
|
if (pd->idlers)
|
|
|
|
efl_event_callback_call(loop, EFL_LOOP_EVENT_IDLE, NULL);
|
2020-02-28 10:47:50 -08:00
|
|
|
eina_freeq_reduce(eina_freeq_main_get(), 256);
|
2017-12-21 02:31:24 -08:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
2018-07-26 13:37:00 -07:00
|
|
|
/* We'll add this one anyway outside this function,
|
|
|
|
don't want it twice */
|
|
|
|
if (fdh->flags & ECORE_FD_ALWAYS)
|
|
|
|
continue;
|
2018-02-20 22:38:30 -08:00
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-06-22 14:41:29 -07:00
|
|
|
_ecore_try_add_to_call_list(obj, pd, 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
|
|
|
{
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
_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);
|
|
|
|
|
2018-06-22 14:41:29 -07:00
|
|
|
if ((pd->timer_fd >= 0) && (t > 0.0))
|
2017-11-08 22:59:04 -08:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2018-06-22 14:41:29 -07:00
|
|
|
r = timerfd_settime(pd->timer_fd, 0, &ts, NULL);
|
2017-11-08 22:59:04 -08:00
|
|
|
if (r < 0)
|
|
|
|
{
|
|
|
|
ERR("timer set returned %d (errno=%d)",
|
|
|
|
r, errno);
|
2018-06-22 14:41:29 -07:00
|
|
|
close(pd->timer_fd);
|
|
|
|
pd->timer_fd = -1;
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
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
|
|
|
{
|
2018-06-22 14:41:29 -07:00
|
|
|
if (pd->timer_fd >= 0)
|
2011-07-05 04:13:39 -07:00
|
|
|
{
|
2011-07-06 03:54:11 -07:00
|
|
|
uint64_t count = 0;
|
2018-06-22 14:41:29 -07:00
|
|
|
int r = read(pd->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);
|
2018-06-22 14:41:29 -07:00
|
|
|
close(pd->timer_fd);
|
|
|
|
pd->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;
|
|
|
|
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
_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();
|
2019-07-28 03:51:15 -07:00
|
|
|
eina_file_statgen_next();
|
2020-02-28 10:47:50 -08:00
|
|
|
_ecore_main_pre_idle_exit();
|
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)
|
|
|
|
{
|
2019-10-14 06:30:03 -07:00
|
|
|
_ecore_main_idler_all_call(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;
|
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();
|
2019-07-28 03:51:15 -07:00
|
|
|
eina_file_statgen_next();
|
2020-02-28 10:47:50 -08:00
|
|
|
_ecore_main_pre_idle_exit();
|
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;
|
2019-07-28 03:51:15 -07:00
|
|
|
eina_file_statgen_next();
|
2020-02-28 10:47:50 -08:00
|
|
|
_ecore_main_pre_idle_exit();
|
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
|
|
|
}
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
_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-05-14 10:08:32 -07:00
|
|
|
efl_replace(&ML_OBJ, NULL);
|
|
|
|
ML_DAT = NULL;
|
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
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
_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
|
|
|
|
{
|
2018-06-22 14:41:29 -07:00
|
|
|
#ifndef USE_G_MAIN_LOOP
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
_ecore_main_loop_iterate_internal(obj, pd, 1);
|
2018-06-22 14:41:29 -07:00
|
|
|
#else
|
|
|
|
g_main_context_iteration(NULL, 0);
|
|
|
|
#endif
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
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;
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
_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
|
|
|
|
{
|
2018-06-22 14:41:29 -07:00
|
|
|
#ifndef USE_G_MAIN_LOOP
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop++;
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
_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;
|
2018-06-22 14:41:29 -07:00
|
|
|
#else
|
|
|
|
return g_main_context_iteration(NULL, may_block);
|
|
|
|
#endif
|
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
|
|
|
{
|
2019-07-19 12:42:09 -07:00
|
|
|
pd->loop_active++;
|
2017-11-08 22:59:04 -08:00
|
|
|
if (obj == ML_OBJ)
|
2015-10-05 00:00:47 -07:00
|
|
|
{
|
2020-05-18 02:27:55 -07:00
|
|
|
#ifdef HAVE_SYSTEMD
|
2020-05-15 04:24:36 -07:00
|
|
|
if (getenv("NOTIFY_SOCKET"))
|
|
|
|
{
|
|
|
|
_ecore_sd_init();
|
|
|
|
if (_ecore_sd_notify) _ecore_sd_notify(0, "READY=1");
|
|
|
|
}
|
2020-05-18 02:27:55 -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;
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
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
|
|
|
|
{
|
2018-06-22 14:41:29 -07:00
|
|
|
#ifndef USE_G_MAIN_LOOP
|
2017-11-08 22:59:04 -08:00
|
|
|
pd->in_loop++;
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
while (!pd->do_quit)
|
|
|
|
_ecore_main_loop_iterate_internal(obj, pd, 0);
|
|
|
|
pd->do_quit = 0;
|
|
|
|
pd->in_loop--;
|
2018-06-22 14:41:29 -07:00
|
|
|
#else
|
|
|
|
if (!pd->do_quit)
|
|
|
|
{
|
|
|
|
if (!ecore_main_loop)
|
|
|
|
ecore_main_loop = g_main_loop_new(NULL, 1);
|
|
|
|
g_main_loop_run(ecore_main_loop);
|
|
|
|
}
|
|
|
|
pd->do_quit = 0;
|
|
|
|
#endif
|
2014-09-01 11:08:49 -07:00
|
|
|
}
|
2019-07-19 12:42:09 -07:00
|
|
|
pd->loop_active--;
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_ecore_main_loop_quit(Eo *obj, Efl_Loop_Data *pd)
|
|
|
|
{
|
2019-07-19 12:42:09 -07:00
|
|
|
if (!pd->loop_active) return;
|
2017-11-08 22:59:04 -08:00
|
|
|
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
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API void
|
2017-11-08 22:59:04 -08:00
|
|
|
ecore_main_loop_iterate(void)
|
|
|
|
{
|
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
|
|
|
efl_loop_iterate(ML_OBJ);
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API int
|
2017-11-08 22:59:04 -08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API void
|
2017-11-08 22:59:04 -08:00
|
|
|
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
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API 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
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API int
|
2014-12-04 05:56:43 -08:00
|
|
|
ecore_main_loop_nested_get(void)
|
|
|
|
{
|
|
|
|
return in_main_loop;
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API Eina_Bool
|
2013-12-07 22:05:51 -08:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API 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;
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API 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);
|
2018-07-26 13:37:00 -07:00
|
|
|
if (fdh->flags & ECORE_FD_ALWAYS)
|
|
|
|
pd->always_fd_handlers = eina_list_append
|
|
|
|
(pd->always_fd_handlers, fdh);
|
2017-11-08 22:59:04 -08:00
|
|
|
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)
|
|
|
|
{
|
2018-05-11 09:28:26 -07:00
|
|
|
void *r = fd_handler->data;
|
|
|
|
|
2017-11-08 22:59:04 -08:00
|
|
|
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;
|
2018-05-11 09:28:26 -07:00
|
|
|
if (pd)
|
|
|
|
{
|
|
|
|
_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);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The main loop is dead by now, so cleanup is required.
|
|
|
|
ECORE_MAGIC_SET(fd_handler, ECORE_MAGIC_NONE);
|
|
|
|
ecore_fd_handler_mp_free(fd_handler);
|
|
|
|
}
|
|
|
|
return r;
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API Ecore_Fd_Handler *
|
2012-11-06 02:49:05 -08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API Ecore_Fd_Handler *
|
2012-08-01 07:37:24 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API void *
|
2017-11-08 22:59:04 -08:00
|
|
|
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
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API 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;
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API Ecore_Win32_Handler *
|
2017-11-08 22:59:04 -08:00
|
|
|
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
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API void *
|
2009-11-23 15:09:48 -08:00
|
|
|
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
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API Ecore_Win32_Handler *
|
2017-11-08 22:59:04 -08:00
|
|
|
_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;
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API Ecore_Win32_Handler *
|
2017-11-08 22:59:04 -08:00
|
|
|
ecore_main_win32_handler_add(void *h EINA_UNUSED,
|
|
|
|
Ecore_Win32_Handle_Cb func EINA_UNUSED,
|
|
|
|
const void *data EINA_UNUSED)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API 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
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API 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
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API int
|
2003-09-23 01:09:32 -07:00
|
|
|
ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
|
|
|
|
{
|
2018-05-15 15:32:14 -07:00
|
|
|
if (!fd_handler) return -1;
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API 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;
|
|
|
|
}
|
|
|
|
|
ecore: Rename EAPI macro to ECORE_API in Ecore library
Summary:
= The Rationale =
EAPI was designed to be able to pass
`__attribute__ ((visibility ("default")))` for symbols with
GCC, which would mean that even if -fvisibility=hidden was used
when compiling the library, the needed symbols would get exported.
MSVC __almost__ works like GCC (or mingw) in which you can
declare everything as export and it will just work (slower, but
it will work). But there's a caveat: global variables will not
work the same way for MSVC, but works for mingw and GCC.
For global variables (as opposed to functions), MSVC requires
correct DSO visibility for MSVC: instead of declaring a symbol as
export for everything, you need to declare it as import when
importing from another DSO and export when defining it locally.
With current EAPI definitions, we get the following example
working in mingw and MSVC (observe it doesn't define any global
variables as exported symbols).
Example 1:
dll1:
```
EAPI void foo(void);
EAPI void bar()
{
foo();
}
```
dll2:
```
EAPI void foo()
{
printf ("foo\n");
}
```
This works fine with API defined as __declspec(dllexport) in both
cases and for gcc defining as
`__atttribute__((visibility("default")))`.
However, the following:
Example 2:
dll1:
```
EAPI extern int foo;
EAPI void foobar(void);
EAPI void bar()
{
foo = 5;
foobar();
}
```
dll2:
```
EAPI int foo = 0;
EAPI void foobar()
{
printf ("foo %d\n", foo);
}
```
This will work on mingw but will not work for MSVC. And that's why
EAPI is the only solution that worked for MSVC.
Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com>
Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev>
Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com>
Reviewers: vtorri, raster
Reviewed By: raster
Subscribers: raster, cedric, #reviewers, #committers
Tags: #efl
Differential Revision: https://phab.enlightenment.org/D12271
2021-05-23 12:08:05 -07:00
|
|
|
ECORE_API 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);
|
2018-07-26 13:37:00 -07:00
|
|
|
if (pd->always_fd_handlers)
|
|
|
|
pd->always_fd_handlers =
|
|
|
|
eina_list_free(pd->always_fd_handlers);
|
2017-12-23 04:07:23 -08:00
|
|
|
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;
|
2018-07-26 13:37:00 -07:00
|
|
|
int max_fd, ret, outval;
|
2017-12-16 23:03:33 -08:00
|
|
|
#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
|
|
|
{
|
2018-07-26 13:37:00 -07:00
|
|
|
if ((fdh->flags & ECORE_FD_READ) || (fdh->flags & ECORE_FD_ALWAYS))
|
2011-07-06 03:54:30 -07:00
|
|
|
{
|
|
|
|
FD_SET(fdh->fd, &rfds);
|
|
|
|
if (fdh->fd > max_fd) max_fd = fdh->fd;
|
|
|
|
}
|
2018-07-26 13:37:00 -07:00
|
|
|
if ((fdh->flags & ECORE_FD_WRITE) || (fdh->flags & ECORE_FD_ALWAYS))
|
2011-07-06 03:54:30 -07:00
|
|
|
{
|
|
|
|
FD_SET(fdh->fd, &wfds);
|
|
|
|
if (fdh->fd > max_fd) max_fd = fdh->fd;
|
|
|
|
}
|
2018-07-26 13:37:00 -07:00
|
|
|
if ((fdh->flags & ECORE_FD_ERROR) || (fdh->flags & ECORE_FD_ALWAYS))
|
2011-07-06 03:54:30 -07:00
|
|
|
{
|
|
|
|
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);
|
2019-10-18 10:29:01 -07:00
|
|
|
if (max_fd > -1)
|
|
|
|
FD_SET(max_fd, &rfds);
|
2017-11-08 22:59:04 -08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
EINA_LIST_FOREACH(pd->file_fd_handlers, l, fdh)
|
|
|
|
{
|
|
|
|
if (!fdh->delete_me)
|
|
|
|
{
|
2018-07-26 13:37:00 -07:00
|
|
|
if ((fdh->flags & ECORE_FD_READ) || (fdh->flags & ECORE_FD_ALWAYS))
|
2017-11-08 22:59:04 -08:00
|
|
|
{
|
|
|
|
FD_SET(fdh->fd, &rfds);
|
|
|
|
if (fdh->fd > max_fd) max_fd = fdh->fd;
|
|
|
|
}
|
2018-07-26 13:37:00 -07:00
|
|
|
if ((fdh->flags & ECORE_FD_WRITE) || (fdh->flags & ECORE_FD_ALWAYS))
|
2017-11-08 22:59:04 -08:00
|
|
|
{
|
|
|
|
FD_SET(fdh->fd, &wfds);
|
|
|
|
if (fdh->fd > max_fd) max_fd = fdh->fd;
|
|
|
|
}
|
2018-07-26 13:37:00 -07:00
|
|
|
if ((fdh->flags & ECORE_FD_ERROR) || (fdh->flags & ECORE_FD_ALWAYS))
|
2017-11-08 22:59:04 -08:00
|
|
|
{
|
|
|
|
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
|
|
|
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2003-09-23 01:09:32 -07:00
|
|
|
if (ret < 0)
|
|
|
|
{
|
2009-11-23 15:09:48 -08:00
|
|
|
#ifndef _WIN32
|
2018-07-26 13:37:00 -07:00
|
|
|
if (err_no == EINTR)
|
|
|
|
{
|
|
|
|
outval = -1;
|
|
|
|
goto BAIL;
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
}
|
2018-07-26 13:37:00 -07:00
|
|
|
outval = 1;
|
|
|
|
goto BAIL;
|
|
|
|
}
|
|
|
|
outval = 0;
|
|
|
|
BAIL:
|
|
|
|
EINA_LIST_FOREACH(pd->always_fd_handlers, l, fdh)
|
|
|
|
_ecore_try_add_to_call_list(obj, pd, fdh);
|
|
|
|
|
|
|
|
if (ret > 0)
|
|
|
|
{
|
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
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
2018-07-26 13:37:00 -07:00
|
|
|
return outval || pd->always_fd_handlers;
|
2003-09-23 01:09:32 -07:00
|
|
|
}
|
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);
|
2018-07-26 13:37:00 -07:00
|
|
|
if (fdh->flags & ECORE_FD_ALWAYS)
|
|
|
|
pd->always_fd_handlers = eina_list_remove(pd->always_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
|
2018-07-18 23:53:49 -07:00
|
|
|
_ecore_main_fd_handlers_call(Eo *obj EINA_UNUSED, 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) ||
|
2018-07-26 13:37:00 -07:00
|
|
|
(fdh->error_active) ||
|
|
|
|
(fdh->flags & ECORE_FD_ALWAYS))
|
2017-11-08 22:59:04 -08:00
|
|
|
{
|
|
|
|
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
|
|
|
{
|
2019-10-14 06:30:03 -07:00
|
|
|
_ecore_main_idler_all_call(obj, pd);
|
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)
|
|
|
|
{
|
2019-07-28 03:51:15 -07:00
|
|
|
eina_file_statgen_next();
|
2020-02-28 10:47:50 -08:00
|
|
|
_ecore_main_pre_idle_exit();
|
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;
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
_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
|
|
|
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
_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
|
2018-08-14 14:09:32 -07:00
|
|
|
_update_loop_time(pd);
|
2017-11-08 22:59:04 -08:00
|
|
|
// call all idlers
|
2019-10-14 06:30:03 -07:00
|
|
|
_ecore_main_idler_all_call(obj, pd);
|
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:
|
2019-07-28 03:51:15 -07:00
|
|
|
eina_file_statgen_next();
|
2020-02-28 10:47:50 -08:00
|
|
|
_ecore_main_pre_idle_exit();
|
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
|