proposal: defer installing SIGCHLD

Denis Bilenko denis.bilenko at gmail.com
Tue May 22 11:21:35 CEST 2012


Hi Marc,

The patch below defers installing SIGCHLD until the first child
watcher is started. Thus, if an application does not use child
watchers, libev never installs a SIGCHLD handler.

The problem I'm solving with it is this:

In gevent 0.x we used libevent which does not reap children. There
were a few 3rd-party packages written for gevent for working with
subprocesses. All of them use waitpid(). These packages stopped
working with gevent 1.x (libev-based), for obvious reason.

I know that I can override libev's SIGCHLD handler with my own, but
it's less than ideal because it requires the user to explicitly
specify whether he wants to do that in advance. I'm much happier with
the patch below, since the old code (using waitpid()) and the new code
(using child watchers) "just works", no configuration required.

Of course, using both the old way and the new way in the same app
still won't work, but that's a reasonable limitation.

Cheers,
Denis.


--- /home/denis/work/libev-cvs/ev.c	2012-05-22 12:52:25.509951601 +0400
+++ ev.c	2012-05-22 12:58:58.427872477 +0400
@@ -2666,8 +2666,6 @@
 #if EV_CHILD_ENABLE
           ev_signal_init (&childev, childcb, SIGCHLD);
           ev_set_priority (&childev, EV_MAXPRI);
-          ev_signal_start (EV_A_ &childev);
-          ev_unref (EV_A); /* child watcher should not keep loop alive */
 #endif
         }
       else
@@ -3594,6 +3592,13 @@
   ev_start (EV_A_ (W)w, 1);
   wlist_add (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w);

+  if (!ev_is_active(&childev))
+    {
+      ev_signal_start (EV_A_ &childev);
+      ev_unref (EV_A); /* child watcher should not keep loop alive */
+      ev_feed_event (EV_A_ (W)&childev, EV_SIGNAL);
+    }
+
   EV_FREQUENT_CHECK;
 }



More information about the libev mailing list