summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ev.c42
-rw-r--r--ev.h1
-rw-r--r--ev_epoll.c2
3 files changed, 34 insertions, 11 deletions
diff --git a/ev.c b/ev.c
index 6c2f397..7bed969 100644
--- a/ev.c
+++ b/ev.c
@@ -478,19 +478,35 @@ static struct ev_signal childev;
#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->rpid = pid;
- w->rstatus = 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
@@ -573,10 +589,12 @@ 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
}
@@ -1010,6 +1028,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)
{
@@ -1027,7 +1049,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);
}
}
diff --git a/ev.h b/ev.h
index 8d2922d..1e88f02 100644
--- a/ev.h
+++ b/ev.h
@@ -168,6 +168,7 @@ struct ev_check
/* invoked when sigchld is received and waitpid indicates the givne pid */
/* revent EV_CHILD */
+/* does not support priorities */
struct ev_child
{
EV_WATCHER_LIST (ev_child);
diff --git a/ev_epoll.c b/ev_epoll.c
index d38672f..a7918af 100644
--- a/ev_epoll.c
+++ b/ev_epoll.c
@@ -75,7 +75,7 @@ epoll_poll (ev_tstamp timeout)
for (i = 0; i < eventcnt; ++i)
fd_event (
- events [i].data.fd,
+ events [i].data.u64,
(events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)
| (events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0)
);