From patchwork Thu Jul 28 20:50:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [4,of,5,STABLE,V2] worker: make waitforworkers reentrant From: Jun Wu X-Patchwork-Id: 16001 Message-Id: <3e52c87875599106cd17.1469739007@x1c> To: Date: Thu, 28 Jul 2016 21:50:07 +0100 # HG changeset patch # User Jun Wu # 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]: