X-Git-Url: https://git.llucax.com/software/libev.git/blobdiff_plain/15231b01d6df419056fbc6d97bc10a2f8f79da00..614930116ff2c76f9954eee0cf4c5194ee4204e0:/ev.c?ds=sidebyside diff --git a/ev.c b/ev.c index 9ff5823..8cb6141 100644 --- a/ev.c +++ b/ev.c @@ -591,7 +591,6 @@ fd_rearm_all (EV_P) { int fd; - /* this should be highly optimised to not do anything but set a flag */ for (fd = 0; fd < anfdmax; ++fd) if (anfds [fd].events) { @@ -889,6 +888,12 @@ ev_backend (EV_P) return backend; } +unsigned int +ev_loop_count (EV_P) +{ + return loop_count; +} + static void noinline loop_init (EV_P_ unsigned int flags) { @@ -907,6 +912,12 @@ loop_init (EV_P_ unsigned int flags) now_floor = mn_now; rtmn_diff = ev_rt_now - mn_now; + /* pid check not overridable via env */ +#ifndef _WIN32 + if (flags & EVFLAG_FORKCHECK) + curpid = getpid (); +#endif + if (!(flags & EVFLAG_NOENV) && !enable_secure () && getenv ("LIBEV_FLAGS")) @@ -1272,10 +1283,10 @@ time_update (EV_P) /* loop a few times, before making important decisions. * on the choice of "4": one iteration isn't enough, * in case we get preempted during the calls to - * ev_time and get_clock. a second call is almost guarenteed + * ev_time and get_clock. a second call is almost guaranteed * to succeed in that case, though. and looping a few more times * doesn't hurt either as we only do this on time-jumps or - * in the unlikely event of getting preempted here. + * in the unlikely event of having been preempted here. */ for (i = 4; --i; ) { @@ -1307,7 +1318,7 @@ time_update (EV_P) periodics_reschedule (EV_A); #endif - /* adjust timers. this is easy, as the offset is the same for all */ + /* adjust timers. this is easy, as the offset is the same for all of them */ for (i = 0; i < timercnt; ++i) ((WT)timers [i])->at += ev_rt_now - mn_now; } @@ -1337,17 +1348,28 @@ ev_loop (EV_P_ int flags) ? EVUNLOOP_ONE : EVUNLOOP_CANCEL; - while (activecnt) + call_pending (EV_A); /* in case we recurse, ensure ordering stays nice and clean */ + + do { - /* we might have forked, so reify kernel state if necessary */ - #if EV_FORK_ENABLE - if (expect_false (postfork)) - if (forkcnt) - { - queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK); - call_pending (EV_A); - } - #endif +#ifndef _WIN32 + if (expect_false (curpid)) /* penalise the forking check even more */ + if (expect_false (getpid () != curpid)) + { + curpid = getpid (); + postfork = 1; + } +#endif + +#if EV_FORK_ENABLE + /* we might have forked, so queue fork handlers */ + if (expect_false (postfork)) + if (forkcnt) + { + queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK); + call_pending (EV_A); + } +#endif /* queue check watchers (and execute them) */ if (expect_false (preparecnt)) @@ -1356,6 +1378,9 @@ ev_loop (EV_P_ int flags) call_pending (EV_A); } + if (expect_false (!activecnt)) + break; + /* we might have forked, so reify kernel state if necessary */ if (expect_false (postfork)) loop_fork (EV_A); @@ -1365,9 +1390,9 @@ ev_loop (EV_P_ int flags) /* calculate blocking time */ { - double block; + ev_tstamp block; - if (flags & EVLOOP_NONBLOCK || idlecnt) + if (expect_false (flags & EVLOOP_NONBLOCK || idlecnt || !activecnt)) block = 0.; /* do not block at all */ else { @@ -1401,6 +1426,7 @@ ev_loop (EV_P_ int flags) if (expect_false (block < 0.)) block = 0.; } + ++loop_count; backend_poll (EV_A_ block); } @@ -1423,9 +1449,8 @@ ev_loop (EV_P_ int flags) call_pending (EV_A); - if (expect_false (loop_done)) - break; } + while (expect_true (activecnt && !loop_done)); if (loop_done == EVUNLOOP_ONE) loop_done = EVUNLOOP_CANCEL; @@ -1720,7 +1745,7 @@ ev_child_stop (EV_P_ ev_child *w) #define DEF_STAT_INTERVAL 5.0074891 #define MIN_STAT_INTERVAL 0.1074891 -void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents); +static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents); #if EV_USE_INOTIFY # define EV_INOTIFY_BUFSIZE 8192 @@ -1881,7 +1906,7 @@ ev_stat_stat (EV_P_ ev_stat *w) w->attr.st_nlink = 1; } -void noinline +static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents) { ev_stat *w = (ev_stat *)(((char *)w_) - offsetof (ev_stat, timer));