summaryrefslogtreecommitdiff
path: root/src/lib/ecore/ecore_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/ecore/ecore_main.c')
-rw-r--r--src/lib/ecore/ecore_main.c189
1 files changed, 109 insertions, 80 deletions
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index 634e87d3f3..4b27e180a2 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -136,6 +136,7 @@ struct _Ecore_Fd_Handler
Eina_Bool error_active : 1;
Eina_Bool delete_me : 1;
Eina_Bool file : 1;
+ Eina_Bool legacy : 1;
};
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Fd_Handler);
@@ -215,7 +216,7 @@ static gboolean ecore_fds_ready;
static inline void
_ecore_fd_valid(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
{
-# ifdef HAVE_EPOLL
+# ifdef HAVE_SYS_EPOLL_H
if ((pd->epoll_fd >= 0) &&
(fcntl(pd->epoll_fd, F_GETFD) < 0))
{
@@ -259,7 +260,7 @@ _throttle_do(Efl_Loop_Data *pd)
eina_evlog("-throttle", NULL, 0.0, NULL);
}
-#ifdef HAVE_EPOLL
+#ifdef HAVE_SYS_EPOLL_H
static inline int
_ecore_get_epoll_fd(Eo *obj, Efl_Loop_Data *pd)
{
@@ -289,9 +290,9 @@ static inline int
_ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh)
{
int events = 0;
- if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN;
- if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT;
- if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR | EPOLLPRI;
+ 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;
return events;
}
#endif
@@ -301,9 +302,9 @@ static inline int
_gfd_events_from_fdh(Ecore_Fd_Handler *fdh)
{
int events = 0;
- if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN;
- if (fdh->flags & ECORE_FD_WRITE) events |= G_IO_OUT;
- if (fdh->flags & ECORE_FD_ERROR) events |= G_IO_ERR;
+ 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;
return events;
}
#endif
@@ -331,6 +332,12 @@ _ecore_main_uv_poll_cb(uv_poll_t *handle, int status, int events)
if (events & UV_READABLE) fdh->read_active = EINA_TRUE;
if (events & UV_WRITABLE) fdh->write_active = EINA_TRUE;
+ if (events & UV_DISCONNECT)
+ {
+ fdh->read_active = EINA_TRUE;
+ fdh->write_active = EINA_TRUE;
+ fdh->error_active = EINA_TRUE;
+ }
_ecore_try_add_to_call_list(obj, pd, fdh);
_ecore_main_fd_handlers_call(obj, pd);
@@ -358,7 +365,7 @@ _ecore_main_fdh_poll_add(Efl_Loop_Data *pd EINA_UNUSED, Ecore_Fd_Handler *fdh)
DBG("_ecore_main_fdh_poll_add");
int r = 0;
-#ifdef HAVE_EPOLL
+#ifdef HAVE_SYS_EPOLL_H
# ifdef HAVE_LIBUV
if (!_dl_uv_run)
# endif
@@ -413,11 +420,17 @@ _ecore_main_fdh_poll_add(Efl_Loop_Data *pd EINA_UNUSED, Ecore_Fd_Handler *fdh)
static inline void
_ecore_main_fdh_poll_del(Efl_Loop_Data *pd, Ecore_Fd_Handler *fdh)
{
-#ifdef HAVE_EPOLL
+#ifdef HAVE_SYS_EPOLL_H
# ifdef HAVE_LIBUV
if (!_dl_uv_run)
# endif
{
+ if (!pd)
+ {
+ WRN("Efl_Loop_Data is NULL!");
+ return;
+ }
+
if ((!fdh->file) && (pd->epoll_fd >= 0))
{
struct epoll_event ev;
@@ -465,7 +478,7 @@ _ecore_main_fdh_poll_modify(Efl_Loop_Data *pd EINA_UNUSED, Ecore_Fd_Handler *fdh
{
DBG("_ecore_main_fdh_poll_modify %p", fdh);
int r = 0;
-#ifdef HAVE_EPOLL
+#ifdef HAVE_SYS_EPOLL_H
# ifdef HAVE_LIBUV
if (!_dl_uv_run)
# endif
@@ -517,7 +530,7 @@ _ecore_main_idler_all_call(Eo *loop)
eina_freeq_reduce(eina_freeq_main_get(), 84);
}
-#ifdef HAVE_EPOLL
+#ifdef HAVE_SYS_EPOLL_H
static inline int
_ecore_main_fdh_epoll_mark_active(Eo *obj, Efl_Loop_Data *pd)
{
@@ -556,6 +569,13 @@ _ecore_main_fdh_epoll_mark_active(Eo *obj, Efl_Loop_Data *pd)
if (ev[i].events & EPOLLOUT) fdh->write_active = EINA_TRUE;
if (ev[i].events & EPOLLERR) fdh->error_active = EINA_TRUE;
+ if (ev[i].events & EPOLLHUP)
+ {
+ fdh->read_active = EINA_TRUE;
+ fdh->write_active = EINA_TRUE;
+ fdh->error_active = EINA_TRUE;
+ }
+
_ecore_try_add_to_call_list(obj, pd, fdh);
}
return ret;
@@ -578,7 +598,14 @@ _ecore_main_fdh_glib_mark_active(Eo *obj, Efl_Loop_Data *pd)
if (fdh->gfd.revents & G_IO_OUT) fdh->write_active = EINA_TRUE;
if (fdh->gfd.revents & G_IO_ERR) fdh->error_active = EINA_TRUE;
- _ecore_try_add_to_call_list(obj, fdh);
+ if (fdh->gfd.revents & G_IO_HUP)
+ {
+ fdh->read_active = EINA_TRUE;
+ fdh->write_active = EINA_TRUE;
+ fdh->error_active = EINA_TRUE;
+ }
+
+ _ecore_try_add_to_call_list(obj, pd, fdh);
if (fdh->gfd.revents & (G_IO_IN | G_IO_OUT | G_IO_ERR)) ret++;
}
@@ -600,7 +627,7 @@ _ecore_main_gsource_prepare(GSource *source EINA_UNUSED,
if ((!ecore_idling) && (!_ecore_glib_idle_enterer_called))
{
- pd->loop_time = _ecore_time_loop_time = ecore_time_get();
+ pd->loop_time = ecore_time_get();
_efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time);
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_ENTER, NULL);
@@ -626,7 +653,7 @@ _ecore_main_gsource_prepare(GSource *source EINA_UNUSED,
int r = -1;
double t = _efl_loop_timer_next_get(obj, pd);
- if ((timer_fd >= 0) && (t > 0.0))
+ if ((pd->timer_fd >= 0) && (t > 0.0))
{
struct itimerspec ts;
@@ -638,13 +665,13 @@ _ecore_main_gsource_prepare(GSource *source EINA_UNUSED,
// timerfd cannot sleep for 0 time
if (ts.it_value.tv_sec || ts.it_value.tv_nsec)
{
- r = timerfd_settime(timer_fd, 0, &ts, NULL);
+ r = timerfd_settime(pd->timer_fd, 0, &ts, NULL);
if (r < 0)
{
ERR("timer set returned %d (errno=%d)",
r, errno);
- close(timer_fd);
- timer_fd = -1;
+ close(pd->timer_fd);
+ pd->timer_fd = -1;
}
else INF("sleeping for %ld s %06ldus",
ts.it_value.tv_sec,
@@ -690,10 +717,10 @@ _ecore_main_gsource_check(GSource *source EINA_UNUSED)
if (ecore_idling && (!_ecore_main_idlers_exist(pd)) &&
(!pd->message_queue))
{
- if (timer_fd >= 0)
+ if (pd->timer_fd >= 0)
{
uint64_t count = 0;
- int r = read(timer_fd, &count, sizeof count);
+ int r = read(pd->timer_fd, &count, sizeof count);
if ((r == -1) && (errno == EAGAIN))
{
}
@@ -702,15 +729,15 @@ _ecore_main_gsource_check(GSource *source EINA_UNUSED)
{
// unexpected things happened... fail back to old way
ERR("timer read returned %d (errno=%d)", r, errno);
- close(timer_fd);
- timer_fd = -1;
+ close(pd->timer_fd);
+ pd->timer_fd = -1;
}
}
}
else ret = TRUE;
// check if fds are ready
-#ifdef HAVE_EPOLL
+#ifdef HAVE_SYS_EPOLL_H
if (pd->epoll_fd >= 0)
ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active(obj, pd) > 0);
else
@@ -871,7 +898,7 @@ _ecore_main_loop_setup(Eo *obj, Efl_Loop_Data *pd)
{
// Please note that this function is being also called in case of a bad
// fd to reset the main loop.
-#ifdef HAVE_EPOLL
+#ifdef HAVE_SYS_EPOLL_H
pd->epoll_fd = epoll_create(1);
if (pd->epoll_fd < 0) WRN("Failed to create epoll fd!");
else
@@ -974,7 +1001,7 @@ _ecore_main_loop_setup(Eo *obj, Efl_Loop_Data *pd)
{
g_source_set_priority(ecore_glib_source,
G_PRIORITY_HIGH_IDLE + 20);
-# ifdef HAVE_EPOLL
+# ifdef HAVE_SYS_EPOLL_H
if (pd->epoll_fd >= 0)
{
// epoll multiplexes fds into the g_main_loop
@@ -1030,7 +1057,7 @@ _ecore_main_loop_clear(Eo *obj, Efl_Loop_Data *pd)
}
#endif
}
-# ifdef HAVE_EPOLL
+# ifdef HAVE_SYS_EPOLL_H
if (pd->epoll_fd >= 0)
{
close(pd->epoll_fd);
@@ -1058,7 +1085,8 @@ _ecore_main_loop_shutdown(void)
if (!ML_OBJ) return;
_ecore_main_loop_clear(ML_OBJ, ML_DAT);
// XXX: this seemingly closes fd's it shouldn't.... :( fd 0?
- efl_del(ML_OBJ);
+ efl_replace(&ML_OBJ, NULL);
+ ML_DAT = NULL;
}
void
@@ -1084,8 +1112,12 @@ _ecore_main_loop_iterate(Eo *obj, Efl_Loop_Data *pd)
}
else
{
+#ifndef USE_G_MAIN_LOOP
pd->loop_time = ecore_time_get();
_ecore_main_loop_iterate_internal(obj, pd, 1);
+#else
+ g_main_context_iteration(NULL, 0);
+#endif
}
}
@@ -1118,11 +1150,15 @@ _ecore_main_loop_iterate_may_block(Eo *obj, Efl_Loop_Data *pd, int may_block)
}
else
{
+#ifndef USE_G_MAIN_LOOP
pd->in_loop++;
pd->loop_time = ecore_time_get();
_ecore_main_loop_iterate_internal(obj, pd, !may_block);
pd->in_loop--;
return pd->message_queue ? 1 : 0;
+#else
+ return g_main_context_iteration(NULL, may_block);
+#endif
}
return 0;
}
@@ -1132,11 +1168,6 @@ _ecore_main_loop_begin(Eo *obj, Efl_Loop_Data *pd)
{
if (obj == ML_OBJ)
{
- if (pd->in_loop > 0)
- {
- ERR("Beginning main loop() inside an existing main loop");
- return;
- }
#ifdef HAVE_SYSTEMD
sd_notify(0, "READY=1");
#endif
@@ -1181,12 +1212,22 @@ _ecore_main_loop_begin(Eo *obj, Efl_Loop_Data *pd)
}
else
{
+#ifndef USE_G_MAIN_LOOP
pd->in_loop++;
pd->loop_time = ecore_time_get();
while (!pd->do_quit)
_ecore_main_loop_iterate_internal(obj, pd, 0);
pd->do_quit = 0;
pd->in_loop--;
+#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
}
}
@@ -1230,10 +1271,9 @@ EAPI void
ecore_main_loop_quit(void)
{
Eina_Value v = EINA_VALUE_EMPTY;
- int val = 0;
eina_value_setup(&v, EINA_VALUE_TYPE_INT);
- eina_value_set(&v, &val);
+ eina_value_set(&v, 0);
EINA_MAIN_LOOP_CHECK_RETURN;
efl_loop_quit(ML_OBJ, v);
}
@@ -1280,7 +1320,7 @@ _ecore_main_fd_handler_add(Eo *obj,
DBG("_ecore_main_fd_handler_add");
Ecore_Fd_Handler *fdh = NULL;
- if ((fd < 0) || (!func)) return NULL;
+ if ((fd < 0) || (flags == 0) || (!func)) return NULL;
fdh = ecore_fd_handler_calloc(1);
if (!fdh) return NULL;
@@ -1320,6 +1360,8 @@ _ecore_main_fd_handler_del(Eo *obj EINA_UNUSED,
Efl_Loop_Data *pd,
Ecore_Fd_Handler *fd_handler)
{
+ void *r = fd_handler->data;
+
DBG("_ecore_main_fd_handler_del %p", fd_handler);
if (fd_handler->delete_me)
{
@@ -1329,16 +1371,25 @@ _ecore_main_fd_handler_del(Eo *obj EINA_UNUSED,
fd_handler->handler = NULL;
fd_handler->delete_me = EINA_TRUE;
- _ecore_main_fdh_poll_del(pd, fd_handler);
- pd->fd_handlers_to_delete = eina_list_append
- (pd->fd_handlers_to_delete, fd_handler);
- if (fd_handler->prep_func && pd->fd_handlers_with_prep)
- pd->fd_handlers_with_prep = eina_list_remove
- (pd->fd_handlers_with_prep, fd_handler);
- if (fd_handler->buf_func && pd->fd_handlers_with_buffer)
- pd->fd_handlers_with_buffer = eina_list_remove
- (pd->fd_handlers_with_buffer, fd_handler);
- return fd_handler->data;
+ 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;
}
EAPI Ecore_Fd_Handler *
@@ -1351,9 +1402,10 @@ ecore_main_fd_handler_add(int fd,
{
Ecore_Fd_Handler *fdh = NULL;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- fdh = _ecore_main_fd_handler_add(efl_loop_main_get(EFL_LOOP_CLASS),
+ fdh = _ecore_main_fd_handler_add(efl_main_loop_get(),
ML_DAT, NULL, fd, flags, func, data,
buf_func, buf_data, EINA_FALSE);
+ if (fdh) fdh->legacy = EINA_TRUE;
return fdh;
}
@@ -1366,7 +1418,7 @@ ecore_main_fd_handler_file_add(int fd,
const void *buf_data)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- return _ecore_main_fd_handler_add(efl_loop_main_get(EFL_LOOP_CLASS),
+ return _ecore_main_fd_handler_add(efl_main_loop_get(),
ML_DAT, NULL, fd, flags, func, data,
buf_func, buf_data, EINA_TRUE);
}
@@ -1498,6 +1550,7 @@ ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler,
Ecore_Fd_Prep_Cb func,
const void *data)
{
+ if (!fd_handler) return;
Efl_Loop_Data *pd = fd_handler->loop_data;
EINA_MAIN_LOOP_CHECK_RETURN;
@@ -1520,6 +1573,8 @@ ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler,
EAPI int
ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
{
+ if (!fd_handler) return -1;
+
EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1);
if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
@@ -1572,20 +1627,9 @@ ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler,
}
void
-_ecore_main_content_clear(Efl_Loop_Data *pd)
+_ecore_main_content_clear(Eo *obj, Efl_Loop_Data *pd)
{
- Efl_Promise *promise;
- Efl_Future *future;
-
- EINA_LIST_FREE(pd->pending_futures, future)
- efl_del(future);
- Eina_List *tmp = pd->pending_promises;
- pd->pending_promises = NULL;
- EINA_LIST_FREE(tmp, promise)
- ecore_loop_promise_fulfill(promise);
-
- // FIXME
- __eina_promise_cancel_all();
+ __eina_promise_cancel_data(obj);
while (pd->fd_handlers)
{
@@ -1594,7 +1638,7 @@ _ecore_main_content_clear(Efl_Loop_Data *pd)
pd->fd_handlers = (Ecore_Fd_Handler *)
eina_inlist_remove(EINA_INLIST_GET(pd->fd_handlers),
EINA_INLIST_GET(fdh));
- if (fdh->handler) efl_del(fdh->handler);
+ if ((fdh->handler) && (fdh->legacy)) efl_del(fdh->handler);
else
{
// XXX: can't do this because this fd handler is legacy and might
@@ -1725,7 +1769,7 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
// call the prepare callback for all handlers
if (pd->fd_handlers_with_prep) _ecore_main_prepare_handlers(obj, pd);
-#ifdef HAVE_EPOLL
+#ifdef HAVE_SYS_EPOLL_H
if (pd->epoll_fd < 0)
{
#endif
@@ -1750,8 +1794,8 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
}
}
}
+#ifdef HAVE_SYS_EPOLL_H
}
-#ifdef HAVE_EPOLL
else
{
// polling on the epoll fd will wake when fd in the epoll set is active
@@ -1805,7 +1849,7 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
}
if (ret > 0)
{
-#ifdef HAVE_EPOLL
+#ifdef HAVE_SYS_EPOLL_H
if (pd->epoll_fd >= 0)
_ecore_main_fdh_epoll_mark_active(obj, pd);
else
@@ -2002,7 +2046,7 @@ _ecore_main_win32_handlers_cleanup(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
#endif
static void
-_ecore_main_fd_handlers_call(Eo *obj, Efl_Loop_Data *pd)
+_ecore_main_fd_handlers_call(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
{
// grab a new list
if (!pd->fd_handlers_to_call_current)
@@ -2281,19 +2325,12 @@ static void
_ecore_main_loop_iterate_internal(Eo *obj, Efl_Loop_Data *pd, int once_only)
{
double next_time = -1.0;
- Eo *f, *p;
if (obj == ML_OBJ)
{
in_main_loop++;
pd->in_loop = in_main_loop;
}
- // destroy all optional futures
- EINA_LIST_FREE(pd->pending_futures, f) efl_del(f);
- // and propagate all promise value
- Eina_List *tmp = pd->pending_promises;
- pd->pending_promises = NULL;
- EINA_LIST_FREE(tmp, p) ecore_loop_promise_fulfill(p);
// expire any timers
_efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time);
// process signals into events ....
@@ -2362,14 +2399,6 @@ _ecore_main_loop_iterate_internal(Eo *obj, Efl_Loop_Data *pd, int once_only)
// start of the sleeping or looping section
start_loop: //-*************************************************************
- // We could be looping here without exiting the function and we need to
- // process future and promise before the next waiting period.
- // destroy all optional futures
- EINA_LIST_FREE(pd->pending_futures, f) efl_del(f);
- // and propagate all promise value
- tmp = pd->pending_promises;
- pd->pending_promises = NULL;
- EINA_LIST_FREE(tmp, p) ecore_loop_promise_fulfill(p);
// any timers re-added as a result of these are allowed to go
_efl_loop_timer_enable_new(obj, pd);
// if we have been asked to quit the mainloop then exit at this point