[PATCH 1 of 3 v2] worker: on error, exit similarly to the first failing worker

Bryan O'Sullivan bos at serpentine.com
Tue Feb 19 14:54:04 CST 2013


# HG changeset patch
# User Bryan O'Sullivan <bryano at fb.com>
# Date 1361307231 28800
# Node ID bd5bb50f9f1660152459d13b921e599b8af96b13
# Parent  c0d3f22e904a4899c61150af296af79a05a9e0c2
worker: on error, exit similarly to the first failing worker

Previously, if a worker failed, we exited with status 1. We now exit
with the correct exit code (killing ourselves if necessary).

diff --git a/mercurial/worker.py b/mercurial/worker.py
--- a/mercurial/worker.py
+++ b/mercurial/worker.py
@@ -92,11 +92,16 @@ def _posixworker(ui, func, staticargs, a
     def cleanup():
         # python 2.4 is too dumb for try/yield/finally
         signal.signal(signal.SIGINT, oldhandler)
-        problems = 0
+        problem = None
         for i in xrange(workers):
-            problems |= os.wait()[1]
-        if problems:
-            sys.exit(1)
+            pid, st = os.wait()
+            st = _exitstatus(st)
+            if st and not problem:
+                problem = st
+        if problem:
+            if problem < 0:
+                os.kill(os.getpid(), -problem)
+            sys.exit(problem)
     try:
         for line in fp:
             l = line.split(' ', 1)
@@ -106,8 +111,19 @@ def _posixworker(ui, func, staticargs, a
         raise
     cleanup()
 
+def _posixexitstatus(code):
+    '''convert a posix exit status into the same form returned by
+    os.spawnv
+
+    returns None if the process was stopped instead of exiting'''
+    if os.WIFEXITED(code):
+        return os.WEXITSTATUS(code)
+    elif os.WIFSIGNALED(code):
+        return -os.WTERMSIG(code)
+
 if os.name != 'nt':
     _platformworker = _posixworker
+    _exitstatus = _posixexitstatus
 
 def partition(lst, nslices):
     '''partition a list into N slices of equal size'''


More information about the Mercurial-devel mailing list