X-Git-Url: https://git.llucax.com/software/libev.git/blobdiff_plain/0e5eb45308c4238186cdad9a9d838dd04394e1bd..6fb30a67f78730c733f64429f327e360ea2acaf3:/ev.c diff --git a/ev.c b/ev.c index 371c62b..a111beb 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 @@ -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); } } @@ -654,7 +662,6 @@ upheap (WT *heap, int k) heap [k] = w; ((W)heap [k])->active = k + 1; - } void inline_speed @@ -795,7 +802,7 @@ siginit (EV_P) /*****************************************************************************/ -static ev_child *childs [EV_PID_HASHSIZE]; +static WL childs [EV_PID_HASHSIZE]; #ifndef _WIN32 @@ -1033,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); @@ -1217,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)));*/ @@ -1230,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 */ @@ -1245,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)));*/ @@ -1254,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 */ @@ -1278,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); @@ -1288,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 @@ -1600,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 @@ -1614,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 @@ -1631,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));*/ } @@ -1645,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; @@ -1653,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); } } @@ -1670,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); @@ -1701,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));*/ } @@ -1715,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; @@ -1723,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); } } @@ -1754,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) { @@ -1779,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) @@ -1796,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 @@ -1806,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); }