[PATCH 7 of 8 V5] worker: add a SIGCHLD handler to collect worker immediately

Jun Wu quark at fb.com
Mon Nov 14 21:39:10 EST 2016


# HG changeset patch
# User Jun Wu <quark at fb.com>
# Date 1478920042 0
#      Sat Nov 12 03:07:22 2016 +0000
# Node ID 3a463b68088ed4721b0b0a33504143b7eff65ade
# Parent  8402c91c250a9dd369296dcdf00f7b50110ff6ae
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 3a463b68088e
worker: add a SIGCHLD handler to collect worker immediately

As planned by previous patches, add a SIGCHLD handler to get notifications
about worker exits, and deals with worker failure immediately.

Note that the SIGCHLD handler gets unregistered before killworkers(), so
SIGCHLD won't interrupt "killworkers" - making it harder to send kill
signals to waited processes.

diff --git a/mercurial/worker.py b/mercurial/worker.py
--- a/mercurial/worker.py
+++ b/mercurial/worker.py
@@ -121,9 +121,15 @@ def _posixworker(ui, func, staticargs, a
             if st and next(problemcount) == 0:
                 problem[0] = st
+                # unregister SIGCHLD handler as all children will be killed
+                signal.signal(signal.SIGCHLD, oldchldhandler)
                 killworkers()
+    def sigchldhandler(signum, frame):
+        waitforworkers(blocking=False)
+    oldchldhandler = signal.signal(signal.SIGCHLD, sigchldhandler)
     for pargs in partition(args, workers):
         pid = os.fork()
         if pid == 0:
             signal.signal(signal.SIGINT, oldhandler)
+            signal.signal(signal.SIGCHLD, oldchldhandler)
             try:
                 os.close(rfd)
@@ -143,4 +149,5 @@ def _posixworker(ui, func, staticargs, a
         signal.signal(signal.SIGINT, oldhandler)
         t.join()
+        signal.signal(signal.SIGCHLD, oldchldhandler)
         status = problem[0]
         if status:


More information about the Mercurial-devel mailing list