X-Git-Url: https://git.llucax.com/software/libev.git/blobdiff_plain/78ab61dd9808cafa50b5bc8c37e49345237c35fe..34a787b55768ddae6645862dc60434188e1fad8d:/ev.c diff --git a/ev.c b/ev.c index 23507bd..3e1e8b4 100644 --- a/ev.c +++ b/ev.c @@ -44,7 +44,9 @@ #include #include #include -#include +#ifndef WIN32 +# include +#endif #include #include @@ -66,6 +68,10 @@ # define EV_USE_EPOLL 0 #endif +#ifndef EV_USE_KQUEUE +# define EV_USE_KQUEUE 0 +#endif + #ifndef EV_USE_REALTIME # define EV_USE_REALTIME 1 #endif @@ -409,8 +415,10 @@ sighandler (int signum) if (!gotsig) { + int old_errno = errno; gotsig = 1; write (sigpipe [1], &signum, 1); + errno = old_errno; } } @@ -436,12 +444,14 @@ sigcb (struct ev_io *iow, int revents) static void siginit (void) { +#ifndef WIN32 fcntl (sigpipe [0], F_SETFD, FD_CLOEXEC); fcntl (sigpipe [1], F_SETFD, FD_CLOEXEC); /* rather than sort out wether we really need nb, set it */ fcntl (sigpipe [0], F_SETFL, O_NONBLOCK); fcntl (sigpipe [1], F_SETFL, O_NONBLOCK); +#endif ev_io_set (&sigev, sigpipe [0], EV_READ); ev_io_start (&sigev); @@ -463,27 +473,51 @@ static int checkmax, checkcnt; static struct ev_child *childs [PID_HASHSIZE]; static struct ev_signal childev; +#ifndef WIN32 + #ifndef WCONTINUED # define WCONTINUED 0 #endif static void -childcb (struct ev_signal *sw, int revents) +child_reap (struct ev_signal *sw, int chain, int pid, int status) { struct ev_child *w; + + for (w = childs [chain & (PID_HASHSIZE - 1)]; w; w = w->next) + if (w->pid == pid || !w->pid) + { + w->priority = sw->priority; /* need to do it *now* */ + w->rpid = pid; + w->rstatus = status; + printf ("rpid %p %d %d\n", w, pid, w->pid);//D + event ((W)w, EV_CHILD); + } +} + +static void +childcb (struct ev_signal *sw, int revents) +{ 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) - { - w->status = status; - event ((W)w, EV_CHILD); - } + printf ("chld %x\n", revents);//D + if (0 < (pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED))) + { + /* make sure we are called again until all childs have been reaped */ + event ((W)sw, EV_SIGNAL); + + child_reap (sw, pid, pid, status); + child_reap (sw, 0, pid, status); /* this might trigger a watcher twice, but event catches that */ + } } +#endif + /*****************************************************************************/ +#if EV_USE_KQUEUE +# include "ev_kqueue.c" +#endif #if EV_USE_EPOLL # include "ev_epoll.c" #endif @@ -506,12 +540,16 @@ ev_version_minor (void) return EV_VERSION_MINOR; } -/* return true if we are running with elevated privileges and ignore env variables */ +/* return true if we are running with elevated privileges and should ignore env variables */ static int enable_secure () { +#ifdef WIN32 + return 0; +#else return getuid () != geteuid () || getgid () != getegid (); +#endif } int ev_init (int methods) @@ -541,6 +579,9 @@ int ev_init (int methods) methods = EVMETHOD_ANY; ev_method = 0; +#if EV_USE_KQUEUE + if (!ev_method && (methods & EVMETHOD_KQUEUE)) kqueue_init (methods); +#endif #if EV_USE_EPOLL if (!ev_method && (methods & EVMETHOD_EPOLL )) epoll_init (methods); #endif @@ -554,10 +595,14 @@ int ev_init (int methods) if (ev_method) { ev_watcher_init (&sigev, sigcb); + ev_set_priority (&sigev, EV_MAXPRI); siginit (); +#ifndef WIN32 ev_signal_init (&childev, childcb, SIGCHLD); + ev_set_priority (&childev, EV_MAXPRI); ev_signal_start (&childev); +#endif } } @@ -860,6 +905,9 @@ ev_clear_pending (W w) static void ev_start (W w, int active) { + if (w->priority < EV_MINPRI) w->priority = EV_MINPRI; + if (w->priority > EV_MAXPRI) w->priority = EV_MAXPRI; + w->active = active; } @@ -986,6 +1034,10 @@ ev_periodic_stop (struct ev_periodic *w) ev_stop ((W)w); } +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif + void ev_signal_start (struct ev_signal *w) { @@ -1003,7 +1055,7 @@ ev_signal_start (struct ev_signal *w) struct sigaction sa; sa.sa_handler = sighandler; sigfillset (&sa.sa_mask); - sa.sa_flags = 0; + sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */ sigaction (w->signum, &sa, 0); } }