[PATCH 4 of 5 STABLE V2] worker: make waitforworkers reentrant

Jun Wu quark at fb.com
Thu Jul 28 16:50:07 EDT 2016


# HG changeset patch
# User Jun Wu <quark at fb.com>
# Date 1469737019 -3600
#      Thu Jul 28 21:16:59 2016 +0100
# Node ID 3e52c87875599106cd17b264df93c903a3876dfb
# Parent  57c3b5c1b41333faa4062720ae50bf93c187ce88
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 3e52c8787559
worker: make waitforworkers reentrant

We are going to use it in SIGCHLD handler. The handler will be executed in the
main thread with the non-blocking version of waitpid, while the waitforworkers
thread runs the blocking version. It's possible that one of them collects a
worker and makes the other error out. This patch handles these error: ECHILD
is ignored. EINTR needs a retry.

diff --git a/mercurial/worker.py b/mercurial/worker.py
--- a/mercurial/worker.py
+++ b/mercurial/worker.py
@@ -96,7 +96,15 @@ def _posixworker(ui, func, staticargs, a
                     raise
     def waitforworkers(blocking=True):
         for pid in pids:
-            p, st = os.waitpid(pid, 0 if blocking else os.WNOHANG)
+            p = st = 0
+            while True:
+                try:
+                    p, st = os.waitpid(pid, 0 if blocking else os.WNOHANG)
+                except OSError as e:
+                    if e.errno == errno.EINTR:
+                        continue
+                    # otherwise it's ECHILD and is ignored
+                break
             if p:
                 st = _exitstatus(s)
             if st and not problem[0]:


More information about the Mercurial-devel mailing list