comparison mercurial/worker.py @ 18707:d1a2b086d058

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).
author Bryan O'Sullivan <bryano@fb.com>
date Wed, 20 Feb 2013 11:31:27 -0800
parents 047110c0e2a8
children 86524a70c0f6
comparison
equal deleted inserted replaced
18706:f17680992123 18707:d1a2b086d058
90 oldhandler = signal.getsignal(signal.SIGINT) 90 oldhandler = signal.getsignal(signal.SIGINT)
91 signal.signal(signal.SIGINT, signal.SIG_IGN) 91 signal.signal(signal.SIGINT, signal.SIG_IGN)
92 def cleanup(): 92 def cleanup():
93 # python 2.4 is too dumb for try/yield/finally 93 # python 2.4 is too dumb for try/yield/finally
94 signal.signal(signal.SIGINT, oldhandler) 94 signal.signal(signal.SIGINT, oldhandler)
95 problems = 0 95 problem = None
96 for i in xrange(workers): 96 for i in xrange(workers):
97 problems |= os.wait()[1] 97 pid, st = os.wait()
98 if problems: 98 st = _exitstatus(st)
99 sys.exit(1) 99 if st and not problem:
100 problem = st
101 if problem:
102 if problem < 0:
103 os.kill(os.getpid(), -problem)
104 sys.exit(problem)
100 try: 105 try:
101 for line in fp: 106 for line in fp:
102 l = line.split(' ', 1) 107 l = line.split(' ', 1)
103 yield int(l[0]), l[1][:-1] 108 yield int(l[0]), l[1][:-1]
104 except: # re-raises 109 except: # re-raises
105 cleanup() 110 cleanup()
106 raise 111 raise
107 cleanup() 112 cleanup()
108 113
114 def _posixexitstatus(code):
115 '''convert a posix exit status into the same form returned by
116 os.spawnv
117
118 returns None if the process was stopped instead of exiting'''
119 if os.WIFEXITED(code):
120 return os.WEXITSTATUS(code)
121 elif os.WIFSIGNALED(code):
122 return -os.WTERMSIG(code)
123
109 if os.name != 'nt': 124 if os.name != 'nt':
110 _platformworker = _posixworker 125 _platformworker = _posixworker
126 _exitstatus = _posixexitstatus
111 127
112 def partition(lst, nslices): 128 def partition(lst, nslices):
113 '''partition a list into N slices of equal size''' 129 '''partition a list into N slices of equal size'''
114 n = len(lst) 130 n = len(lst)
115 chunk, slop = n / nslices, n % nslices 131 chunk, slop = n / nslices, n % nslices