Patchwork [4,of,4] worker: discard waited pid by anyone who noticed it first

login
register
mail settings
Submitter Yuya Nishihara
Date Nov. 17, 2016, 1:20 p.m.
Message ID <5e9721975f8cda7daea6.1479388802@mimosa>
Download mbox | patch
Permalink /patch/17615/
State Accepted
Headers show

Comments

Yuya Nishihara - Nov. 17, 2016, 1:20 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1479383829 -32400
#      Thu Nov 17 20:57:09 2016 +0900
# Node ID 5e9721975f8cda7daea6ee0cc6aaad7af5096a08
# Parent  4be342413ddecd0eb6d76c4e5d8bb38fee28061d
worker: discard waited pid by anyone who noticed it first

This makes sure all waited pids are removed before calling killworkers()
even if waitpid()-pids.discard() sequence is interrupted by another SIGCHLD.
via Mercurial-devel - Nov. 17, 2016, 5:33 p.m.
Queued this. Thanks, and thanks to Jun for reviewing.

On Thu, Nov 17, 2016 at 5:20 AM, Yuya Nishihara <yuya@tcha.org> wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1479383829 -32400
> #      Thu Nov 17 20:57:09 2016 +0900
> # Node ID 5e9721975f8cda7daea6ee0cc6aaad7af5096a08
> # Parent  4be342413ddecd0eb6d76c4e5d8bb38fee28061d
> worker: discard waited pid by anyone who noticed it first
>
> This makes sure all waited pids are removed before calling killworkers()
> even if waitpid()-pids.discard() sequence is interrupted by another SIGCHLD.
>
> diff --git a/mercurial/worker.py b/mercurial/worker.py
> --- a/mercurial/worker.py
> +++ b/mercurial/worker.py
> @@ -111,11 +111,14 @@ def _posixworker(ui, func, staticargs, a
>                      if e.errno == errno.EINTR:
>                          continue
>                      elif e.errno == errno.ECHILD:
> -                        break # ignore ECHILD
> +                        # child would already be reaped, but pids yet been
> +                        # updated (maybe interrupted just after waitpid)
> +                        pids.discard(pid)
> +                        break
>                      else:
>                          raise
>              if p:
> -                pids.remove(p)
> +                pids.discard(p)
>                  st = _exitstatus(st)
>              if st and not problem[0]:
>                  problem[0] = st
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/worker.py b/mercurial/worker.py
--- a/mercurial/worker.py
+++ b/mercurial/worker.py
@@ -111,11 +111,14 @@  def _posixworker(ui, func, staticargs, a
                     if e.errno == errno.EINTR:
                         continue
                     elif e.errno == errno.ECHILD:
-                        break # ignore ECHILD
+                        # child would already be reaped, but pids yet been
+                        # updated (maybe interrupted just after waitpid)
+                        pids.discard(pid)
+                        break
                     else:
                         raise
             if p:
-                pids.remove(p)
+                pids.discard(p)
                 st = _exitstatus(st)
             if st and not problem[0]:
                 problem[0] = st