X-Git-Url: https://git.llucax.com/software/libev.git/blobdiff_plain/32d31146fc7b464e5934da588ba7278da5944e0b..6800c1e86d28e4bc573747e6d327c770b2e00df4:/ev.c diff --git a/ev.c b/ev.c index 810c10a..8911cb8 100644 --- a/ev.c +++ b/ev.c @@ -158,6 +158,14 @@ extern "C" { # define EV_USE_PORT 0 #endif +#ifndef EV_PID_HASHSIZE +# if EV_MINIMAL +# define EV_PID_HASHSIZE 1 +# else +# define EV_PID_HASHSIZE 16 +# endif +#endif + /**/ #ifndef CLOCK_MONOTONIC @@ -178,7 +186,6 @@ extern "C" { #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ #define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */ -#define PID_HASHSIZE 16 /* size of pid hash table, must be power of two */ /*#define CLEANUP_INTERVAL (MAX_BLOCKTIME * 5.) /* how often to try to free memory and re-check fds */ #ifdef EV_H @@ -711,7 +718,7 @@ siginit (EV_P) /*****************************************************************************/ -static ev_child *childs [PID_HASHSIZE]; +static ev_child *childs [EV_PID_HASHSIZE]; #ifndef _WIN32 @@ -722,7 +729,7 @@ child_reap (EV_P_ ev_signal *sw, int chain, int pid, int status) { ev_child *w; - for (w = (ev_child *)childs [chain & (PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next) + for (w = (ev_child *)childs [chain & (EV_PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next) if (w->pid == pid || !w->pid) { ev_priority (w) = ev_priority (sw); /* need to do it *now* */ @@ -753,7 +760,8 @@ childcb (EV_P_ ev_signal *sw, int revents) ev_feed_event (EV_A_ (W)sw, EV_SIGNAL); child_reap (EV_A_ sw, pid, pid, status); - child_reap (EV_A_ sw, 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */ + if (EV_PID_HASHSIZE > 1) + child_reap (EV_A_ sw, 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */ } #endif @@ -1278,6 +1286,16 @@ ev_loop (EV_P_ int flags) while (activecnt) { + /* 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 + /* queue check watchers (and execute them) */ if (expect_false (preparecnt)) { @@ -1617,7 +1635,7 @@ ev_child_start (EV_P_ ev_child *w) return; ev_start (EV_A_ (W)w, 1); - wlist_add ((WL *)&childs [w->pid & (PID_HASHSIZE - 1)], (WL)w); + wlist_add ((WL *)&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w); } void @@ -1627,14 +1645,15 @@ ev_child_stop (EV_P_ ev_child *w) if (expect_false (!ev_is_active (w))) return; - wlist_del ((WL *)&childs [w->pid & (PID_HASHSIZE - 1)], (WL)w); + wlist_del ((WL *)&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w); ev_stop (EV_A_ (W)w); } #if EV_STAT_ENABLE # ifdef _WIN32 -# define lstat(a,b) stat(a,b) +# undef lstat +# define lstat(a,b) _stati64 (a,b) # endif #define DEF_STAT_INTERVAL 5.0074891 @@ -1828,6 +1847,35 @@ ev_embed_stop (EV_P_ ev_embed *w) } #endif +#if EV_FORK_ENABLE +void +ev_fork_start (EV_P_ ev_fork *w) +{ + if (expect_false (ev_is_active (w))) + return; + + ev_start (EV_A_ (W)w, ++forkcnt); + array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2); + forks [forkcnt - 1] = w; +} + +void +ev_fork_stop (EV_P_ ev_fork *w) +{ + ev_clear_pending (EV_A_ (W)w); + if (expect_false (!ev_is_active (w))) + return; + + { + int active = ((W)w)->active; + forks [active - 1] = forks [--forkcnt]; + ((W)forks [active - 1])->active = active; + } + + ev_stop (EV_A_ (W)w); +} +#endif + /*****************************************************************************/ struct ev_once