X-Git-Url: https://git.llucax.com/software/libev.git/blobdiff_plain/62e079bb6850faefce26c3930818dba3659cbda8..4f1dc6c0e6bd6e6e6edab0e55fc6b96824a12f38:/ev.c?ds=sidebyside diff --git a/ev.c b/ev.c index 342a097..299ba00 100644 --- a/ev.c +++ b/ev.c @@ -37,23 +37,27 @@ extern "C" { # 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_WORKING_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 @@ -159,7 +163,9 @@ typedef struct ev_watcher_time *WT; static int have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */ -#include "ev_win32.c" +#ifdef WIN32 +# include "ev_win32.c" +#endif /*****************************************************************************/ @@ -229,6 +235,7 @@ typedef struct 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 @@ -251,7 +258,7 @@ typedef struct /*****************************************************************************/ -inline ev_tstamp +ev_tstamp ev_time (void) { #if EV_USE_REALTIME @@ -530,15 +537,10 @@ downheap (WT *heap, int N, int k) } 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); } /*****************************************************************************/ @@ -806,7 +808,9 @@ loop_destroy (EV_P) /* 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); @@ -989,7 +993,11 @@ timers_reify (EV_P) 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 @@ -999,6 +1007,7 @@ timers_reify (EV_P) } } +#if EV_PERIODICS static void periodics_reify (EV_P) { @@ -1049,6 +1058,7 @@ periodics_reschedule (EV_P) for (i = periodiccnt >> 1; i--; ) downheap ((WT *)periodics, periodiccnt, i); } +#endif inline int time_update_monotonic (EV_P) @@ -1092,7 +1102,9 @@ time_update (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) */ } @@ -1104,7 +1116,9 @@ time_update (EV_P) 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) @@ -1177,11 +1191,13 @@ ev_loop (EV_P_ int flags) 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.; } @@ -1193,7 +1209,9 @@ ev_loop (EV_P_ int flags) /* 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)) @@ -1294,6 +1312,8 @@ ev_io_stop (EV_P_ struct ev_io *w) if (!ev_is_active (w)) return; + assert (("ev_io_start called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax)); + wlist_del ((WL *)&anfds[w->fd].head, (WL)w); ev_stop (EV_A_ (W)w); @@ -1330,10 +1350,10 @@ ev_timer_stop (EV_P_ struct ev_timer *w) 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); } @@ -1344,7 +1364,10 @@ ev_timer_again (EV_P_ struct ev_timer *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); } @@ -1352,6 +1375,7 @@ ev_timer_again (EV_P_ struct ev_timer *w) ev_timer_start (EV_A_ w); } +#if EV_PERIODICS void ev_periodic_start (EV_P_ struct ev_periodic *w) { @@ -1387,7 +1411,7 @@ ev_periodic_stop (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); @@ -1400,6 +1424,7 @@ ev_periodic_again (EV_P_ struct ev_periodic *w) ev_periodic_stop (EV_A_ w); ev_periodic_start (EV_A_ w); } +#endif void ev_idle_start (EV_P_ struct ev_idle *w) @@ -1460,7 +1485,7 @@ void 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]; @@ -1531,7 +1556,7 @@ void 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);