[PATCH 6 of 7 V3] worker: test and set problem[0] atomically
Jun Wu
quark at fb.com
Thu Aug 4 18:29:07 UTC 2016
# HG changeset patch
# User Jun Wu <quark at fb.com>
# Date 1470334096 -3600
# Thu Aug 04 19:08:16 2016 +0100
# Node ID d08d72f5d8bf302dd1231be410d0b23dc082eb66
# Parent d179a66b0b15988687ba9d69c5b76e4464a457eb
# Available At https://bitbucket.org/quark-zju/hg-draft
# hg pull https://bitbucket.org/quark-zju/hg-draft -r d08d72f5d8bf
worker: test and set problem[0] atomically
Previously problem[0] is not tested and set atomically:
if st and not problem[0]:
# at this time, another SIGCHILD happens, killworkers may run twice
problem[0] = st
killworkers()
This patch addresses the issue by using itertools.count(). Its CPython
implementation will make it "atomic" at the Python code level, which is
enough for our use-case (signal handler).
diff --git a/mercurial/worker.py b/mercurial/worker.py
--- a/mercurial/worker.py
+++ b/mercurial/worker.py
@@ -8,6 +8,7 @@
from __future__ import absolute_import
import errno
+import itertools
import os
import signal
import sys
@@ -86,6 +87,7 @@ def _posixworker(ui, func, staticargs, a
oldhandler = signal.getsignal(signal.SIGINT)
signal.signal(signal.SIGINT, signal.SIG_IGN)
pids, problem = [], [0]
+ problemcount = itertools.count()
def killworkers():
# if one worker bails, there's no good reason to wait for the rest
for p in pids:
@@ -107,7 +109,7 @@ def _posixworker(ui, func, staticargs, a
break
if p:
st = _exitstatus(st)
- if st and not problem[0]:
+ if st and next(problemcount) == 0:
problem[0] = st
killworkers()
def sigchldhandler(signum, frame):
More information about the Mercurial-devel
mailing list