worker: on error, exit similarly to the first failing worker
authorBryan O'Sullivan <bryano@fb.com>
Wed, 20 Feb 2013 11:31:27 -0800
changeset 18707 d1a2b086d058
parent 18706 f17680992123
child 18708 86524a70c0f6
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).
mercurial/worker.py
--- a/mercurial/worker.py	Tue Feb 19 13:35:39 2013 -0600
+++ b/mercurial/worker.py	Wed Feb 20 11:31:27 2013 -0800
@@ -92,11 +92,16 @@
     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 @@
         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'''