X-Git-Url: https://git.llucax.com/software/libev.git/blobdiff_plain/b2ebd839862b60e3a71179138dd201e7c8a4fa61..cc491ddade261fb0e1755c6da29a95f1c66e8b32:/ev.c diff --git a/ev.c b/ev.c index ffd19c6..b2e48f8 100644 --- a/ev.c +++ b/ev.c @@ -38,6 +38,8 @@ #include #include +#include +#include #include #include @@ -61,6 +63,7 @@ #define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ #define MAX_BLOCKTIME 60. +#define PID_HASHSIZE 16 /* size of pid hahs table, must be power of two */ #include "ev.h" @@ -334,6 +337,30 @@ static int checkmax, checkcnt; /*****************************************************************************/ +static struct ev_child *childs [PID_HASHSIZE]; +static struct ev_signal childev; + +#ifndef WCONTINUED +# define WCONTINUED 0 +#endif + +static void +childcb (struct ev_signal *sw, int revents) +{ + struct ev_child *w; + int pid, status; + + while ((pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED)) != -1) + for (w = childs [pid & (PID_HASHSIZE - 1)]; w; w = w->next) + if (w->pid == pid || w->pid == -1) + { + w->status = status; + event ((W)w, EV_CHILD); + } +} + +/*****************************************************************************/ + #if HAVE_EPOLL # include "ev_epoll.c" #endif @@ -370,6 +397,9 @@ int ev_init (int flags) { evw_init (&sigev, sigcb); siginit (); + + evsignal_init (&childev, childcb, SIGCHLD); + evsignal_start (&childev); } return ev_method; @@ -881,6 +911,25 @@ void evcheck_stop (struct ev_check *w) ev_stop ((W)w); } +void evchild_start (struct ev_child *w) +{ + if (ev_is_active (w)) + return; + + ev_start ((W)w, 1); + wlist_add ((WL *)&childs [w->pid & (PID_HASHSIZE - 1)], (WL)w); +} + +void evchild_stop (struct ev_child *w) +{ + ev_clear ((W)w); + if (ev_is_active (w)) + return; + + wlist_del ((WL *)&childs [w->pid & (PID_HASHSIZE - 1)], (WL)w); + ev_stop ((W)w); +} + /*****************************************************************************/ struct ev_once