Mercurial > hg
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 |