Show More
@@ -6,7 +6,7 b'' | |||||
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | from i18n import _ |
|
8 | from i18n import _ | |
9 | import os, signal, sys, util |
|
9 | import os, signal, sys, threading, util | |
10 |
|
10 | |||
11 | def countcpus(): |
|
11 | def countcpus(): | |
12 | '''try to count the number of CPUs on the system''' |
|
12 | '''try to count the number of CPUs on the system''' | |
@@ -77,6 +77,7 b' def _posixworker(ui, func, staticargs, a' | |||||
77 | workers = _numworkers(ui) |
|
77 | workers = _numworkers(ui) | |
78 | oldhandler = signal.getsignal(signal.SIGINT) |
|
78 | oldhandler = signal.getsignal(signal.SIGINT) | |
79 | signal.signal(signal.SIGINT, signal.SIG_IGN) |
|
79 | signal.signal(signal.SIGINT, signal.SIG_IGN) | |
|
80 | pids, problem = [], [0] | |||
80 | for pargs in partition(args, workers): |
|
81 | for pargs in partition(args, workers): | |
81 | pid = os.fork() |
|
82 | pid = os.fork() | |
82 | if pid == 0: |
|
83 | if pid == 0: | |
@@ -88,26 +89,40 b' def _posixworker(ui, func, staticargs, a' | |||||
88 | os._exit(0) |
|
89 | os._exit(0) | |
89 | except KeyboardInterrupt: |
|
90 | except KeyboardInterrupt: | |
90 | os._exit(255) |
|
91 | os._exit(255) | |
|
92 | pids.append(pid) | |||
|
93 | pids.reverse() | |||
91 | os.close(wfd) |
|
94 | os.close(wfd) | |
92 | fp = os.fdopen(rfd, 'rb', 0) |
|
95 | fp = os.fdopen(rfd, 'rb', 0) | |
|
96 | def killworkers(): | |||
|
97 | # if one worker bails, there's no good reason to wait for the rest | |||
|
98 | for p in pids: | |||
|
99 | try: | |||
|
100 | os.kill(p, signal.SIGTERM) | |||
|
101 | except OSError, err: | |||
|
102 | if err.errno != errno.ESRCH: | |||
|
103 | raise | |||
|
104 | def waitforworkers(): | |||
|
105 | for _ in pids: | |||
|
106 | st = _exitstatus(os.wait()[1]) | |||
|
107 | if st and not problem: | |||
|
108 | problem[0] = st | |||
|
109 | killworkers() | |||
|
110 | t = threading.Thread(target=waitforworkers) | |||
|
111 | t.start() | |||
93 | def cleanup(): |
|
112 | def cleanup(): | |
94 | # python 2.4 is too dumb for try/yield/finally |
|
|||
95 | signal.signal(signal.SIGINT, oldhandler) |
|
113 | signal.signal(signal.SIGINT, oldhandler) | |
96 | problem = None |
|
114 | t.join() | |
97 | for i in xrange(workers): |
|
115 | status = problem[0] | |
98 | pid, st = os.wait() |
|
116 | if status: | |
99 |
|
|
117 | if status < 0: | |
100 | if st and not problem: |
|
118 | os.kill(os.getpid(), -status) | |
101 | problem = st |
|
119 | sys.exit(status) | |
102 | if problem: |
|
|||
103 | if problem < 0: |
|
|||
104 | os.kill(os.getpid(), -problem) |
|
|||
105 | sys.exit(problem) |
|
|||
106 | try: |
|
120 | try: | |
107 | for line in fp: |
|
121 | for line in fp: | |
108 | l = line.split(' ', 1) |
|
122 | l = line.split(' ', 1) | |
109 | yield int(l[0]), l[1][:-1] |
|
123 | yield int(l[0]), l[1][:-1] | |
110 | except: # re-raises |
|
124 | except: # re-raises | |
|
125 | killworkers() | |||
111 | cleanup() |
|
126 | cleanup() | |
112 | raise |
|
127 | raise | |
113 | cleanup() |
|
128 | cleanup() |
General Comments 0
You need to be logged in to leave comments.
Login now