X-Git-Url: https://git.llucax.com/software/libev.git/blobdiff_plain/4ce77a5b1de05dae6092eae478b2a4397173d9c3..b3c85cba31a5669ce3e1995d8660542354957a53:/ev.c diff --git a/ev.c b/ev.c index acde504..32369d3 100644 --- a/ev.c +++ b/ev.c @@ -204,11 +204,8 @@ extern "C" { # define EV_USE_REALTIME 0 #endif -#if EV_SELECT_IS_WINSOCKET -# include -#endif - #if !EV_STAT_ENABLE +# undef EV_USE_INOTIFY # define EV_USE_INOTIFY 0 #endif @@ -216,6 +213,10 @@ extern "C" { # include #endif +#if EV_SELECT_IS_WINSOCKET +# include +#endif + /**/ /* @@ -232,7 +233,7 @@ extern "C" { #define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */ /*#define CLEANUP_INTERVAL (MAX_BLOCKTIME * 5.) /* how often to try to free memory and re-check fds, TODO */ -#if __GNUC__ >= 3 +#if __GNUC__ >= 4 # define expect(expr,value) __builtin_expect ((expr),(value)) # define noinline __attribute__ ((noinline)) #else @@ -478,7 +479,7 @@ ev_feed_event (EV_P_ void *w, int revents) } } -void inline_size +void inline_speed queue_events (EV_P_ W *events, int eventcnt, int type) { int i; @@ -535,10 +536,10 @@ fd_reify (EV_P) ANFD *anfd = anfds + fd; ev_io *w; - int events = 0; + unsigned char events = 0; for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next) - events |= w->events; + events |= (unsigned char)w->events; #if EV_SELECT_IS_WINSOCKET if (events) @@ -549,26 +550,33 @@ fd_reify (EV_P) } #endif - anfd->reify = 0; + { + unsigned char o_events = anfd->events; + unsigned char o_reify = anfd->reify; + + anfd->reify = 0; + anfd->events = events; - backend_modify (EV_A_ fd, anfd->events, events); - anfd->events = events; + if (o_events != events || o_reify & EV_IOFDSET) + backend_modify (EV_A_ fd, o_events, events); + } } fdchangecnt = 0; } void inline_size -fd_change (EV_P_ int fd) +fd_change (EV_P_ int fd, int flags) { - if (expect_false (anfds [fd].reify)) - return; - - anfds [fd].reify = 1; + unsigned char reify = anfds [fd].reify; + anfds [fd].reify |= flags; - ++fdchangecnt; - array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2); - fdchanges [fdchangecnt - 1] = fd; + if (expect_true (!reify)) + { + ++fdchangecnt; + array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2); + fdchanges [fdchangecnt - 1] = fd; + } } void inline_speed @@ -629,7 +637,7 @@ fd_rearm_all (EV_P) if (anfds [fd].events) { anfds [fd].events = 0; - fd_change (EV_A_ fd); + fd_change (EV_A_ fd, EV_IOFDSET | 1); } } @@ -640,16 +648,20 @@ upheap (WT *heap, int k) { WT w = heap [k]; - while (k && heap [k >> 1]->at > w->at) + while (k) { - heap [k] = heap [k >> 1]; + int p = (k - 1) >> 1; + + if (heap [p]->at <= w->at) + break; + + heap [k] = heap [p]; ((W)heap [k])->active = k + 1; - k >>= 1; + k = p; } heap [k] = w; ((W)heap [k])->active = k + 1; - } void inline_speed @@ -657,19 +669,23 @@ downheap (WT *heap, int N, int k) { WT w = heap [k]; - while (k < (N >> 1)) + for (;;) { - int j = k << 1; + int c = (k << 1) + 1; + + if (c >= N) + break; - if (j + 1 < N && heap [j]->at > heap [j + 1]->at) - ++j; + c += c + 1 < N && heap [c]->at > heap [c + 1]->at + ? 1 : 0; - if (w->at <= heap [j]->at) + if (w->at <= heap [c]->at) break; - heap [k] = heap [j]; + heap [k] = heap [c]; ((W)heap [k])->active = k + 1; - k = j; + + k = c; } heap [k] = w; @@ -786,7 +802,7 @@ siginit (EV_P) /*****************************************************************************/ -static ev_child *childs [EV_PID_HASHSIZE]; +static WL childs [EV_PID_HASHSIZE]; #ifndef _WIN32 @@ -1024,11 +1040,16 @@ loop_destroy (EV_P) #endif } + ev_free (anfds); anfdmax = 0; + /* have to use the microsoft-never-gets-it-right macro */ array_free (fdchange, EMPTY); array_free (timer, EMPTY); #if EV_PERIODIC_ENABLE array_free (periodic, EMPTY); +#endif +#if EV_FORK_ENABLE + array_free (fork, EMPTY); #endif array_free (prepare, EMPTY); array_free (check, EMPTY); @@ -1208,7 +1229,7 @@ timers_reify (EV_P) { while (timercnt && ((WT)timers [0])->at <= mn_now) { - ev_timer *w = timers [0]; + ev_timer *w = (ev_timer *)timers [0]; /*assert (("inactive timer on timer heap detected", ev_is_active (w)));*/ @@ -1221,7 +1242,7 @@ timers_reify (EV_P) if (((WT)w)->at < mn_now) ((WT)w)->at = mn_now; - downheap ((WT *)timers, timercnt, 0); + downheap (timers, timercnt, 0); } else ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */ @@ -1236,7 +1257,7 @@ periodics_reify (EV_P) { while (periodiccnt && ((WT)periodics [0])->at <= ev_rt_now) { - ev_periodic *w = periodics [0]; + ev_periodic *w = (ev_periodic *)periodics [0]; /*assert (("inactive timer on periodic heap detected", ev_is_active (w)));*/ @@ -1245,14 +1266,14 @@ periodics_reify (EV_P) { ((WT)w)->at = w->reschedule_cb (w, ev_rt_now + TIME_EPSILON); assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > ev_rt_now)); - downheap ((WT *)periodics, periodiccnt, 0); + downheap (periodics, periodiccnt, 0); } else if (w->interval) { ((WT)w)->at = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval; if (((WT)w)->at - ev_rt_now <= TIME_EPSILON) ((WT)w)->at += w->interval; assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > ev_rt_now)); - downheap ((WT *)periodics, periodiccnt, 0); + downheap (periodics, periodiccnt, 0); } else ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */ @@ -1269,7 +1290,7 @@ periodics_reschedule (EV_P) /* adjust periodics after time jump */ for (i = 0; i < periodiccnt; ++i) { - ev_periodic *w = periodics [i]; + ev_periodic *w = (ev_periodic *)periodics [i]; if (w->reschedule_cb) ((WT)w)->at = w->reschedule_cb (w, ev_rt_now); @@ -1279,7 +1300,7 @@ periodics_reschedule (EV_P) /* now rebuild the heap */ for (i = periodiccnt >> 1; i--; ) - downheap ((WT *)periodics, periodiccnt, i); + downheap (periodics, periodiccnt, i); } #endif @@ -1591,9 +1612,10 @@ ev_io_start (EV_P_ ev_io *w) ev_start (EV_A_ (W)w, 1); array_needsize (ANFD, anfds, anfdmax, fd + 1, anfds_init); - wlist_add ((WL *)&anfds[fd].head, (WL)w); + wlist_add (&anfds[fd].head, (WL)w); - fd_change (EV_A_ fd); + fd_change (EV_A_ fd, w->events & EV_IOFDSET | 1); + w->events &= ~EV_IOFDSET; } void noinline @@ -1605,10 +1627,10 @@ ev_io_stop (EV_P_ ev_io *w) 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); + wlist_del (&anfds[w->fd].head, (WL)w); ev_stop (EV_A_ (W)w); - fd_change (EV_A_ w->fd); + fd_change (EV_A_ w->fd, 1); } void noinline @@ -1622,9 +1644,9 @@ ev_timer_start (EV_P_ ev_timer *w) assert (("ev_timer_start called with negative timer repeat value", w->repeat >= 0.)); ev_start (EV_A_ (W)w, ++timercnt); - array_needsize (ev_timer *, timers, timermax, timercnt, EMPTY2); - timers [timercnt - 1] = w; - upheap ((WT *)timers, timercnt - 1); + array_needsize (WT, timers, timermax, timercnt, EMPTY2); + timers [timercnt - 1] = (WT)w; + upheap (timers, timercnt - 1); /*assert (("internal timer heap corruption", timers [((W)w)->active - 1] == w));*/ } @@ -1636,7 +1658,7 @@ ev_timer_stop (EV_P_ ev_timer *w) if (expect_false (!ev_is_active (w))) return; - assert (("internal timer heap corruption", timers [((W)w)->active - 1] == w)); + assert (("internal timer heap corruption", timers [((W)w)->active - 1] == (WT)w)); { int active = ((W)w)->active; @@ -1644,7 +1666,7 @@ ev_timer_stop (EV_P_ ev_timer *w) if (expect_true (--active < --timercnt)) { timers [active] = timers [timercnt]; - adjustheap ((WT *)timers, timercnt, active); + adjustheap (timers, timercnt, active); } } @@ -1661,7 +1683,7 @@ ev_timer_again (EV_P_ ev_timer *w) if (w->repeat) { ((WT)w)->at = mn_now + w->repeat; - adjustheap ((WT *)timers, timercnt, ((W)w)->active - 1); + adjustheap (timers, timercnt, ((W)w)->active - 1); } else ev_timer_stop (EV_A_ w); @@ -1692,9 +1714,9 @@ ev_periodic_start (EV_P_ ev_periodic *w) ((WT)w)->at = w->offset; ev_start (EV_A_ (W)w, ++periodiccnt); - array_needsize (ev_periodic *, periodics, periodicmax, periodiccnt, EMPTY2); - periodics [periodiccnt - 1] = w; - upheap ((WT *)periodics, periodiccnt - 1); + array_needsize (WT, periodics, periodicmax, periodiccnt, EMPTY2); + periodics [periodiccnt - 1] = (WT)w; + upheap (periodics, periodiccnt - 1); /*assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == w));*/ } @@ -1706,7 +1728,7 @@ ev_periodic_stop (EV_P_ ev_periodic *w) if (expect_false (!ev_is_active (w))) return; - assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == w)); + assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == (WT)w)); { int active = ((W)w)->active; @@ -1714,7 +1736,7 @@ ev_periodic_stop (EV_P_ ev_periodic *w) if (expect_true (--active < --periodiccnt)) { periodics [active] = periodics [periodiccnt]; - adjustheap ((WT *)periodics, periodiccnt, active); + adjustheap (periodics, periodiccnt, active); } } @@ -1745,9 +1767,22 @@ ev_signal_start (EV_P_ ev_signal *w) assert (("ev_signal_start called with illegal signal number", w->signum > 0)); + { +#ifndef _WIN32 + sigset_t full, prev; + sigfillset (&full); + sigprocmask (SIG_SETMASK, &full, &prev); +#endif + + array_needsize (ANSIG, signals, signalmax, w->signum, signals_init); + +#ifndef _WIN32 + sigprocmask (SIG_SETMASK, &prev, 0); +#endif + } + ev_start (EV_A_ (W)w, 1); - array_needsize (ANSIG, signals, signalmax, w->signum, signals_init); - wlist_add ((WL *)&signals [w->signum - 1].head, (WL)w); + wlist_add (&signals [w->signum - 1].head, (WL)w); if (!((WL)w)->next) { @@ -1770,7 +1805,7 @@ ev_signal_stop (EV_P_ ev_signal *w) if (expect_false (!ev_is_active (w))) return; - wlist_del ((WL *)&signals [w->signum - 1].head, (WL)w); + wlist_del (&signals [w->signum - 1].head, (WL)w); ev_stop (EV_A_ (W)w); if (!signals [w->signum - 1].head) @@ -1787,7 +1822,7 @@ ev_child_start (EV_P_ ev_child *w) return; ev_start (EV_A_ (W)w, 1); - wlist_add ((WL *)&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w); + wlist_add (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w); } void @@ -1797,7 +1832,7 @@ ev_child_stop (EV_P_ ev_child *w) if (expect_false (!ev_is_active (w))) return; - wlist_del ((WL *)&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w); + wlist_del (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w); ev_stop (EV_A_ (W)w); } @@ -2149,7 +2184,7 @@ ev_check_stop (EV_P_ ev_check *w) void noinline ev_embed_sweep (EV_P_ ev_embed *w) { - ev_loop (w->loop, EVLOOP_NONBLOCK); + ev_loop (w->other, EVLOOP_NONBLOCK); } static void @@ -2170,7 +2205,7 @@ ev_embed_start (EV_P_ ev_embed *w) return; { - struct ev_loop *loop = w->loop; + struct ev_loop *loop = w->other; assert (("loop to be embedded is not embeddable", backend & ev_embeddable_backends ())); ev_io_init (&w->io, embed_cb, backend_fd, EV_READ); } @@ -2287,6 +2322,10 @@ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, vo } } +#if EV_MULTIPLICITY + #include "ev_wrap.h" +#endif + #ifdef __cplusplus } #endif