# include "config.h"
# if HAVE_CLOCK_GETTIME
-# define EV_USE_MONOTONIC 1
-# define EV_USE_REALTIME 1
+# ifndef EV_USE_MONOTONIC
+# define EV_USE_MONOTONIC 1
+# endif
+# ifndef EV_USE_REALTIME
+# define EV_USE_REALTIME 1
+# endif
# endif
-# if HAVE_SELECT && HAVE_SYS_SELECT_H
+# if HAVE_SELECT && HAVE_SYS_SELECT_H && !defined (EV_USE_SELECT)
# define EV_USE_SELECT 1
# endif
-# if HAVE_POLL && HAVE_POLL_H
+# if HAVE_POLL && HAVE_POLL_H && !defined (EV_USE_POLL)
# define EV_USE_POLL 1
# endif
-# if HAVE_EPOLL && HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H
+# if HAVE_EPOLL && HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H && !defined (EV_USE_EPOLL)
# define EV_USE_EPOLL 1
# endif
-# if HAVE_KQUEUE && HAVE_SYS_EVENT_H && HAVE_SYS_QUEUE_H
+# if HAVE_KQUEUE && HAVE_SYS_EVENT_H && HAVE_SYS_QUEUE_H && !defined (EV_USE_KQUEUE)
# define EV_USE_KQUEUE 1
# endif
static int have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
-#include "ev_win32.c"
+#ifdef WIN32
+# include "ev_win32.c"
+#endif
/*****************************************************************************/
struct ev_loop
{
ev_tstamp ev_rt_now;
+ #define ev_rt_now ((loop)->ev_rt_now)
#define VAR(name,decl) decl;
#include "ev_vars.h"
#undef VAR
/*****************************************************************************/
-inline ev_tstamp
+ev_tstamp
ev_time (void)
{
#if EV_USE_REALTIME
}
inline void
-adjustheap (WT *heap, int N, int k, ev_tstamp at)
+adjustheap (WT *heap, int N, int k)
{
- ev_tstamp old_at = heap [k]->at;
- heap [k]->at = at;
-
- if (old_at < at)
- downheap (heap, N, k);
- else
- upheap (heap, k);
+ upheap (heap, k);
+ downheap (heap, N, k);
}
/*****************************************************************************/
/* have to use the microsoft-never-gets-it-right macro */
array_free_microshit (fdchange);
array_free_microshit (timer);
+#if EV_PERIODICS
array_free_microshit (periodic);
+#endif
array_free_microshit (idle);
array_free_microshit (prepare);
array_free_microshit (check);
if (w->repeat)
{
assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.));
- ((WT)w)->at = mn_now + w->repeat;
+
+ ((WT)w)->at += w->repeat;
+ if (((WT)w)->at < mn_now)
+ ((WT)w)->at = mn_now;
+
downheap ((WT *)timers, timercnt, 0);
}
else
}
}
+#if EV_PERIODICS
static void
periodics_reify (EV_P)
{
for (i = periodiccnt >> 1; i--; )
downheap ((WT *)periodics, periodiccnt, i);
}
+#endif
inline int
time_update_monotonic (EV_P)
now_floor = mn_now;
}
+# if EV_PERIODICS
periodics_reschedule (EV_A);
+# endif
/* no timer adjustment, as the monotonic clock doesn't jump */
/* timers_reschedule (EV_A_ rtmn_diff - odiff) */
}
if (expect_false (mn_now > ev_rt_now || mn_now < ev_rt_now - MAX_BLOCKTIME - MIN_TIMEJUMP))
{
+#if EV_PERIODICS
periodics_reschedule (EV_A);
+#endif
/* adjust timers. this is easy, as the offset is the same for all */
for (i = 0; i < timercnt; ++i)
if (block > to) block = to;
}
+#if EV_PERIODICS
if (periodiccnt)
{
ev_tstamp to = ((WT)periodics [0])->at - ev_rt_now + method_fudge;
if (block > to) block = to;
}
+#endif
if (block < 0.) block = 0.;
}
/* queue pending timers and reschedule them */
timers_reify (EV_A); /* relative timers called last */
+#if EV_PERIODICS
periodics_reify (EV_A); /* absolute timers called first */
+#endif
/* queue idle watchers unless io or timers are pending */
if (idlecnt && !any_pending (EV_A))
if (((W)w)->active < timercnt--)
{
timers [((W)w)->active - 1] = timers [timercnt];
- downheap ((WT *)timers, timercnt, ((W)w)->active - 1);
+ adjustheap ((WT *)timers, timercnt, ((W)w)->active - 1);
}
- ((WT)w)->at = w->repeat;
+ ((WT)w)->at -= mn_now;
ev_stop (EV_A_ (W)w);
}
if (ev_is_active (w))
{
if (w->repeat)
- adjustheap ((WT *)timers, timercnt, ((W)w)->active - 1, mn_now + w->repeat);
+ {
+ ((WT)w)->at = mn_now + w->repeat;
+ adjustheap ((WT *)timers, timercnt, ((W)w)->active - 1);
+ }
else
ev_timer_stop (EV_A_ w);
}
ev_timer_start (EV_A_ w);
}
+#if EV_PERIODICS
void
ev_periodic_start (EV_P_ struct ev_periodic *w)
{
if (((W)w)->active < periodiccnt--)
{
periodics [((W)w)->active - 1] = periodics [periodiccnt];
- downheap ((WT *)periodics, periodiccnt, ((W)w)->active - 1);
+ adjustheap ((WT *)periodics, periodiccnt, ((W)w)->active - 1);
}
ev_stop (EV_A_ (W)w);
ev_periodic_stop (EV_A_ w);
ev_periodic_start (EV_A_ w);
}
+#endif
void
ev_idle_start (EV_P_ struct ev_idle *w)
ev_idle_stop (EV_P_ struct ev_idle *w)
{
ev_clear_pending (EV_A_ (W)w);
- if (ev_is_active (w))
+ if (!ev_is_active (w))
return;
idles [((W)w)->active - 1] = idles [--idlecnt];
ev_prepare_stop (EV_P_ struct ev_prepare *w)
{
ev_clear_pending (EV_A_ (W)w);
- if (ev_is_active (w))
+ if (!ev_is_active (w))
return;
prepares [((W)w)->active - 1] = prepares [--preparecnt];
ev_check_stop (EV_P_ struct ev_check *w)
{
ev_clear_pending (EV_A_ (W)w);
- if (ev_is_active (w))
+ if (!ev_is_active (w))
return;
checks [((W)w)->active - 1] = checks [--checkcnt];
ev_child_stop (EV_P_ struct ev_child *w)
{
ev_clear_pending (EV_A_ (W)w);
- if (ev_is_active (w))
+ if (!ev_is_active (w))
return;
wlist_del ((WL *)&childs [w->pid & (PID_HASHSIZE - 1)], (WL)w);