summaryrefslogtreecommitdiff
path: root/ev.c
diff options
context:
space:
mode:
authorroot <root>2007-10-31 19:07:43 +0000
committerroot <root>2007-10-31 19:07:43 +0000
commitcc491ddade261fb0e1755c6da29a95f1c66e8b32 (patch)
tree0fd42606e0298fee137ec99b37702f4c6d7dc77a /ev.c
parentb2ebd839862b60e3a71179138dd201e7c8a4fa61 (diff)
include child watcher
Diffstat (limited to 'ev.c')
-rw-r--r--ev.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/ev.c b/ev.c
index ffd19c6..b2e48f8 100644
--- a/ev.c
+++ b/ev.c
@@ -38,6 +38,8 @@
#include <assert.h>
#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>
@@ -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