[PATCH 5 of 8 V4] worker: make waitforworkers reentrant

Yuya Nishihara yuya at tcha.org
Mon Nov 14 08:04:53 EST 2016


On Sat, 12 Nov 2016 03:11:36 +0000, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu <quark at fb.com>
> # Date 1469737019 -3600
> #      Thu Jul 28 21:16:59 2016 +0100
> # Node ID ca128e326027530210f6509e3ec8b28b97bdce12
> # Parent  10d4102eab371e6b6fcbfef92af6fe9457aabcc4
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #              hg pull https://bitbucket.org/quark-zju/hg-draft -r ca128e326027
> 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,18 @@ 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)
> +        for pid in pids.copy():
> +            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
> +                    elif e.errno == errno.ECHLD:
> +                        break # ignore ECHLD

s/ECHLD/ECHILD/

(worker.py isn't well covered by the automated test.)


More information about the Mercurial-devel mailing list