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

login
register
mail settings
Submitter Jun Wu
Date July 28, 2016, 8:50 p.m.
Message ID <3e52c87875599106cd17.1469739007@x1c>
Download mbox | patch
Permalink /patch/16001/
State Rejected
Delegated to: Yuya Nishihara
Headers show

Comments

Jun Wu - July 28, 2016, 8:50 p.m.
# HG changeset patch
# User Jun Wu <quark@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.

Patch

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]: