Show More
@@ -134,7 +134,17 def _posixworker(ui, func, staticargs, a | |||||
134 | killworkers() |
|
134 | killworkers() | |
135 | oldchldhandler = signal.signal(signal.SIGCHLD, sigchldhandler) |
|
135 | oldchldhandler = signal.signal(signal.SIGCHLD, sigchldhandler) | |
136 | ui.flush() |
|
136 | ui.flush() | |
|
137 | parentpid = os.getpid() | |||
137 | for pargs in partition(args, workers): |
|
138 | for pargs in partition(args, workers): | |
|
139 | # make sure we use os._exit in all worker code paths. otherwise the | |||
|
140 | # worker may do some clean-ups which could cause surprises like | |||
|
141 | # deadlock. see sshpeer.cleanup for example. | |||
|
142 | # override error handling *before* fork. this is necessary because | |||
|
143 | # exception (signal) may arrive after fork, before "pid =" assignment | |||
|
144 | # completes, and other exception handler (dispatch.py) can lead to | |||
|
145 | # unexpected code path without os._exit. | |||
|
146 | ret = -1 | |||
|
147 | try: | |||
138 | pid = os.fork() |
|
148 | pid = os.fork() | |
139 | if pid == 0: |
|
149 | if pid == 0: | |
140 | signal.signal(signal.SIGINT, oldhandler) |
|
150 | signal.signal(signal.SIGINT, oldhandler) | |
@@ -146,24 +156,20 def _posixworker(ui, func, staticargs, a | |||||
146 | os.write(wfd, '%d %s\n' % (i, item)) |
|
156 | os.write(wfd, '%d %s\n' % (i, item)) | |
147 | return 0 |
|
157 | return 0 | |
148 |
|
158 | |||
149 | # make sure we use os._exit in all code paths. otherwise the worker |
|
159 | ret = scmutil.callcatch(ui, workerfunc) | |
150 | # may do some clean-ups which could cause surprises like deadlock. |
|
160 | except: # parent re-raises, child never returns | |
151 | # see sshpeer.cleanup for example. |
|
161 | if os.getpid() == parentpid: | |
152 |
|
|
162 | raise | |
|
163 | exctype = sys.exc_info()[0] | |||
|
164 | force = not issubclass(exctype, KeyboardInterrupt) | |||
|
165 | ui.traceback(force=force) | |||
|
166 | finally: | |||
|
167 | if os.getpid() != parentpid: | |||
153 | try: |
|
168 | try: | |
154 | try: |
|
|||
155 | ret = scmutil.callcatch(ui, workerfunc) |
|
|||
156 | finally: |
|
|||
157 | ui.flush() |
|
169 | ui.flush() | |
158 | except KeyboardInterrupt: |
|
170 | except: # never returns, no re-raises | |
159 |
|
|
171 | pass | |
160 | except: # never return, therefore no re-raises |
|
|||
161 | try: |
|
|||
162 | ui.traceback(force=True) |
|
|||
163 | ui.flush() |
|
|||
164 | finally: |
|
172 | finally: | |
165 | os._exit(255) |
|
|||
166 | else: |
|
|||
167 | os._exit(ret & 255) |
|
173 | os._exit(ret & 255) | |
168 | pids.add(pid) |
|
174 | pids.add(pid) | |
169 | os.close(wfd) |
|
175 | os.close(wfd) |
@@ -91,4 +91,36 Traceback must be printed for unknown ex | |||||
91 | > test 100000.0 exc 2>&1 | grep '^Traceback' |
|
91 | > test 100000.0 exc 2>&1 | grep '^Traceback' | |
92 | Traceback (most recent call last): |
|
92 | Traceback (most recent call last): | |
93 |
|
93 | |||
|
94 | Workers should not do cleanups in all cases | |||
|
95 | ||||
|
96 | $ cat > $TESTTMP/detectcleanup.py <<EOF | |||
|
97 | > from __future__ import absolute_import | |||
|
98 | > import atexit | |||
|
99 | > import os | |||
|
100 | > import time | |||
|
101 | > oldfork = os.fork | |||
|
102 | > count = 0 | |||
|
103 | > parentpid = os.getpid() | |||
|
104 | > def delayedfork(): | |||
|
105 | > global count | |||
|
106 | > count += 1 | |||
|
107 | > pid = oldfork() | |||
|
108 | > # make it easier to test SIGTERM hitting other workers when they have | |||
|
109 | > # not set up error handling yet. | |||
|
110 | > if count > 1 and pid == 0: | |||
|
111 | > time.sleep(0.1) | |||
|
112 | > return pid | |||
|
113 | > os.fork = delayedfork | |||
|
114 | > def cleanup(): | |||
|
115 | > if os.getpid() != parentpid: | |||
|
116 | > os.write(1, 'should never happen\n') | |||
|
117 | > atexit.register(cleanup) | |||
|
118 | > EOF | |||
|
119 | ||||
|
120 | $ hg --config "extensions.t=$abspath" --config worker.numcpus=8 --config \ | |||
|
121 | > "extensions.d=$TESTTMP/detectcleanup.py" test 100000 abort | |||
|
122 | start | |||
|
123 | abort: known exception | |||
|
124 | [255] | |||
|
125 | ||||
94 | #endif |
|
126 | #endif |
General Comments 0
You need to be logged in to leave comments.
Login now