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).
--- 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'''