#endif
#ifndef EV_STANDALONE
-# include "config.h"
+# ifdef EV_CONFIG_H
+# include EV_CONFIG_H
+# else
+# include "config.h"
+# endif
# if HAVE_CLOCK_GETTIME
# ifndef EV_USE_MONOTONIC
#define EMPTY0 /* required for microsofts broken pseudo-c compiler */
#define EMPTY2(a,b) /* used to suppress some warnings */
-typedef struct ev_watcher *W;
-typedef struct ev_watcher_list *WL;
-typedef struct ev_watcher_time *WT;
+typedef ev_watcher *W;
+typedef ev_watcher_list *WL;
+typedef ev_watcher_time *WT;
static int have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
fd_event (EV_P_ int fd, int revents)
{
ANFD *anfd = anfds + fd;
- struct ev_io *w;
+ ev_io *w;
- for (w = (struct ev_io *)anfd->head; w; w = (struct ev_io *)((WL)w)->next)
+ for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next)
{
int ev = w->events & revents;
{
int fd = fdchanges [i];
ANFD *anfd = anfds + fd;
- struct ev_io *w;
+ ev_io *w;
int events = 0;
- for (w = (struct ev_io *)anfd->head; w; w = (struct ev_io *)((WL)w)->next)
+ for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next)
events |= w->events;
#if EV_SELECT_IS_WINSOCKET
static void
fd_kill (EV_P_ int fd)
{
- struct ev_io *w;
+ ev_io *w;
- while ((w = (struct ev_io *)anfds [fd].head))
+ while ((w = (ev_io *)anfds [fd].head))
{
ev_io_stop (EV_A_ w);
ev_feed_event (EV_A_ (W)w, EV_ERROR | EV_READ | EV_WRITE);
static int sigpipe [2];
static sig_atomic_t volatile gotsig;
-static struct ev_io sigev;
+static ev_io sigev;
static void
signals_init (ANSIG *base, int count)
}
static void
-sigcb (EV_P_ struct ev_io *iow, int revents)
+sigcb (EV_P_ ev_io *iow, int revents)
{
int signum;
/*****************************************************************************/
-static struct ev_child *childs [PID_HASHSIZE];
+static ev_child *childs [PID_HASHSIZE];
#ifndef _WIN32
-static struct ev_signal childev;
+static ev_signal childev;
#ifndef WCONTINUED
# define WCONTINUED 0
#endif
static void
-child_reap (EV_P_ struct ev_signal *sw, int chain, int pid, int status)
+child_reap (EV_P_ ev_signal *sw, int chain, int pid, int status)
{
- struct ev_child *w;
+ ev_child *w;
- for (w = (struct ev_child *)childs [chain & (PID_HASHSIZE - 1)]; w; w = (struct ev_child *)((WL)w)->next)
+ for (w = (ev_child *)childs [chain & (PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next)
if (w->pid == pid || !w->pid)
{
ev_priority (w) = ev_priority (sw); /* need to do it *now* */
}
static void
-childcb (EV_P_ struct ev_signal *sw, int revents)
+childcb (EV_P_ ev_signal *sw, int revents)
{
int pid, status;
return flags;
}
+unsigned int
+ev_embeddable_backends (void)
+{
+ return EVBACKEND_EPOLL
+ | EVBACKEND_KQUEUE
+ | EVBACKEND_PORT;
+}
+
unsigned int
ev_backend (EV_P)
{
{
while (timercnt && ((WT)timers [0])->at <= mn_now)
{
- struct ev_timer *w = timers [0];
+ ev_timer *w = timers [0];
assert (("inactive timer on timer heap detected", ev_is_active (w)));
{
while (periodiccnt && ((WT)periodics [0])->at <= ev_rt_now)
{
- struct ev_periodic *w = periodics [0];
+ ev_periodic *w = periodics [0];
assert (("inactive timer on periodic heap detected", ev_is_active (w)));
/* adjust periodics after time jump */
for (i = 0; i < periodiccnt; ++i)
{
- struct ev_periodic *w = periodics [i];
+ ev_periodic *w = periodics [i];
if (w->reschedule_cb)
((WT)w)->at = w->reschedule_cb (w, ev_rt_now);
void
ev_loop (EV_P_ int flags)
{
- double block;
- loop_done = flags & (EVLOOP_ONESHOT | EVLOOP_NONBLOCK) ? 1 : 0;
+ loop_done = flags & (EVLOOP_ONESHOT | EVLOOP_NONBLOCK)
+ ? EVUNLOOP_ONE
+ : EVUNLOOP_CANCEL;
while (activecnt)
{
fd_reify (EV_A);
/* calculate blocking time */
+ {
+ double block;
- /* we only need this for !monotonic clock or timers, but as we basically
- always have timers, we just calculate it always */
+ if (flags & EVLOOP_NONBLOCK || idlecnt)
+ block = 0.; /* do not block at all */
+ else
+ {
+ /* update time to cancel out callback processing overhead */
#if EV_USE_MONOTONIC
- if (expect_true (have_monotonic))
- time_update_monotonic (EV_A);
- else
+ if (expect_true (have_monotonic))
+ time_update_monotonic (EV_A);
+ else
#endif
- {
- ev_rt_now = ev_time ();
- mn_now = ev_rt_now;
- }
+ {
+ ev_rt_now = ev_time ();
+ mn_now = ev_rt_now;
+ }
- if (flags & EVLOOP_NONBLOCK || idlecnt)
- block = 0.;
- else
- {
- block = MAX_BLOCKTIME;
+ block = MAX_BLOCKTIME;
- if (timercnt)
- {
- ev_tstamp to = ((WT)timers [0])->at - mn_now + backend_fudge;
- if (block > to) block = to;
- }
+ if (timercnt)
+ {
+ ev_tstamp to = ((WT)timers [0])->at - mn_now + backend_fudge;
+ if (block > to) block = to;
+ }
#if EV_PERIODICS
- if (periodiccnt)
- {
- ev_tstamp to = ((WT)periodics [0])->at - ev_rt_now + backend_fudge;
- if (block > to) block = to;
- }
+ if (periodiccnt)
+ {
+ ev_tstamp to = ((WT)periodics [0])->at - ev_rt_now + backend_fudge;
+ if (block > to) block = to;
+ }
#endif
- if (expect_false (block < 0.)) block = 0.;
- }
+ if (expect_false (block < 0.)) block = 0.;
+ }
- backend_poll (EV_A_ block);
+ backend_poll (EV_A_ block);
+ }
/* update ev_rt_now, do magic */
time_update (EV_A);
periodics_reify (EV_A); /* absolute timers called first */
#endif
- /* queue idle watchers unless io or timers are pending */
+ /* queue idle watchers unless other events are pending */
if (idlecnt && !any_pending (EV_A))
queue_events (EV_A_ (W *)idles, idlecnt, EV_IDLE);
break;
}
- if (loop_done != 2)
- loop_done = 0;
+ if (loop_done == EVUNLOOP_ONE)
+ loop_done = EVUNLOOP_CANCEL;
}
void
/*****************************************************************************/
void
-ev_io_start (EV_P_ struct ev_io *w)
+ev_io_start (EV_P_ ev_io *w)
{
int fd = w->fd;
}
void
-ev_io_stop (EV_P_ struct ev_io *w)
+ev_io_stop (EV_P_ ev_io *w)
{
ev_clear_pending (EV_A_ (W)w);
if (expect_false (!ev_is_active (w)))
}
void
-ev_timer_start (EV_P_ struct ev_timer *w)
+ev_timer_start (EV_P_ ev_timer *w)
{
if (expect_false (ev_is_active (w)))
return;
assert (("ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
ev_start (EV_A_ (W)w, ++timercnt);
- array_needsize (struct ev_timer *, timers, timermax, timercnt, EMPTY2);
+ array_needsize (ev_timer *, timers, timermax, timercnt, EMPTY2);
timers [timercnt - 1] = w;
upheap ((WT *)timers, timercnt - 1);
}
void
-ev_timer_stop (EV_P_ struct ev_timer *w)
+ev_timer_stop (EV_P_ ev_timer *w)
{
ev_clear_pending (EV_A_ (W)w);
if (expect_false (!ev_is_active (w)))
}
void
-ev_timer_again (EV_P_ struct ev_timer *w)
+ev_timer_again (EV_P_ ev_timer *w)
{
if (ev_is_active (w))
{
#if EV_PERIODICS
void
-ev_periodic_start (EV_P_ struct ev_periodic *w)
+ev_periodic_start (EV_P_ ev_periodic *w)
{
if (expect_false (ev_is_active (w)))
return;
}
ev_start (EV_A_ (W)w, ++periodiccnt);
- array_needsize (struct ev_periodic *, periodics, periodicmax, periodiccnt, EMPTY2);
+ array_needsize (ev_periodic *, periodics, periodicmax, periodiccnt, EMPTY2);
periodics [periodiccnt - 1] = w;
upheap ((WT *)periodics, periodiccnt - 1);
}
void
-ev_periodic_stop (EV_P_ struct ev_periodic *w)
+ev_periodic_stop (EV_P_ ev_periodic *w)
{
ev_clear_pending (EV_A_ (W)w);
if (expect_false (!ev_is_active (w)))
}
void
-ev_periodic_again (EV_P_ struct ev_periodic *w)
+ev_periodic_again (EV_P_ ev_periodic *w)
{
/* TODO: use adjustheap and recalculation */
ev_periodic_stop (EV_A_ w);
#endif
void
-ev_idle_start (EV_P_ struct ev_idle *w)
+ev_idle_start (EV_P_ ev_idle *w)
{
if (expect_false (ev_is_active (w)))
return;
ev_start (EV_A_ (W)w, ++idlecnt);
- array_needsize (struct ev_idle *, idles, idlemax, idlecnt, EMPTY2);
+ array_needsize (ev_idle *, idles, idlemax, idlecnt, EMPTY2);
idles [idlecnt - 1] = w;
}
void
-ev_idle_stop (EV_P_ struct ev_idle *w)
+ev_idle_stop (EV_P_ ev_idle *w)
{
ev_clear_pending (EV_A_ (W)w);
if (expect_false (!ev_is_active (w)))
}
void
-ev_prepare_start (EV_P_ struct ev_prepare *w)
+ev_prepare_start (EV_P_ ev_prepare *w)
{
if (expect_false (ev_is_active (w)))
return;
ev_start (EV_A_ (W)w, ++preparecnt);
- array_needsize (struct ev_prepare *, prepares, preparemax, preparecnt, EMPTY2);
+ array_needsize (ev_prepare *, prepares, preparemax, preparecnt, EMPTY2);
prepares [preparecnt - 1] = w;
}
void
-ev_prepare_stop (EV_P_ struct ev_prepare *w)
+ev_prepare_stop (EV_P_ ev_prepare *w)
{
ev_clear_pending (EV_A_ (W)w);
if (expect_false (!ev_is_active (w)))
}
void
-ev_check_start (EV_P_ struct ev_check *w)
+ev_check_start (EV_P_ ev_check *w)
{
if (expect_false (ev_is_active (w)))
return;
ev_start (EV_A_ (W)w, ++checkcnt);
- array_needsize (struct ev_check *, checks, checkmax, checkcnt, EMPTY2);
+ array_needsize (ev_check *, checks, checkmax, checkcnt, EMPTY2);
checks [checkcnt - 1] = w;
}
void
-ev_check_stop (EV_P_ struct ev_check *w)
+ev_check_stop (EV_P_ ev_check *w)
{
ev_clear_pending (EV_A_ (W)w);
if (expect_false (!ev_is_active (w)))
#endif
void
-ev_signal_start (EV_P_ struct ev_signal *w)
+ev_signal_start (EV_P_ ev_signal *w)
{
#if EV_MULTIPLICITY
assert (("signal watchers are only supported in the default loop", loop == ev_default_loop_ptr));
}
void
-ev_signal_stop (EV_P_ struct ev_signal *w)
+ev_signal_stop (EV_P_ ev_signal *w)
{
ev_clear_pending (EV_A_ (W)w);
if (expect_false (!ev_is_active (w)))
}
void
-ev_child_start (EV_P_ struct ev_child *w)
+ev_child_start (EV_P_ ev_child *w)
{
#if EV_MULTIPLICITY
assert (("child watchers are only supported in the default loop", loop == ev_default_loop_ptr));
}
void
-ev_child_stop (EV_P_ struct ev_child *w)
+ev_child_stop (EV_P_ ev_child *w)
{
ev_clear_pending (EV_A_ (W)w);
if (expect_false (!ev_is_active (w)))
ev_stop (EV_A_ (W)w);
}
+#if EV_MULTIPLICITY
+void
+ev_embed_sweep (EV_P_ ev_embed *w)
+{
+ ev_loop (w->loop, EVLOOP_NONBLOCK);
+}
+
+static void
+embed_cb (EV_P_ ev_io *io, int revents)
+{
+ ev_embed *w = (ev_embed *)(((char *)io) - offsetof (ev_embed, io));
+
+ if (ev_cb (w))
+ ev_feed_event (EV_A_ (W)w, EV_EMBED);
+ else
+ ev_embed_sweep (loop, w);
+}
+
+void
+ev_embed_start (EV_P_ ev_embed *w)
+{
+ if (expect_false (ev_is_active (w)))
+ return;
+
+ {
+ struct ev_loop *loop = w->loop;
+ assert (("loop to be embedded is not embeddable", backend & ev_embeddable_backends ()));
+ ev_io_init (&w->io, embed_cb, backend_fd, EV_READ);
+ }
+
+ ev_set_priority (&w->io, ev_priority (w));
+ ev_io_start (EV_A_ &w->io);
+ ev_start (EV_A_ (W)w, 1);
+}
+
+void
+ev_embed_stop (EV_P_ ev_embed *w)
+{
+ ev_clear_pending (EV_A_ (W)w);
+ if (expect_false (!ev_is_active (w)))
+ return;
+
+ ev_io_stop (EV_A_ &w->io);
+ ev_stop (EV_A_ (W)w);
+}
+#endif
+
/*****************************************************************************/
struct ev_once
{
- struct ev_io io;
- struct ev_timer to;
+ ev_io io;
+ ev_timer to;
void (*cb)(int revents, void *arg);
void *arg;
};
}
static void
-once_cb_io (EV_P_ struct ev_io *w, int revents)
+once_cb_io (EV_P_ ev_io *w, int revents)
{
once_cb (EV_A_ (struct ev_once *)(((char *)w) - offsetof (struct ev_once, io)), revents);
}
static void
-once_cb_to (EV_P_ struct ev_timer *w, int revents)
+once_cb_to (EV_P_ ev_timer *w, int revents)
{
once_cb (EV_A_ (struct ev_once *)(((char *)w) - offsetof (struct ev_once, to)), revents);
}