Mercurial > public > mercurial-scm > hg
comparison mercurial/worker.py @ 30415:e8fb03cfbbde
worker: add a SIGCHLD handler to collect worker immediately
As planned by previous patches, add a SIGCHLD handler to get notifications
about worker exits, and deals with worker failure immediately.
Note that the SIGCHLD handler gets unregistered before killworkers(), so
SIGCHLD won't interrupt "killworkers" - making it harder to send kill
signals to waited processes.
author | Jun Wu <quark@fb.com> |
---|---|
date | Sat, 12 Nov 2016 03:07:22 +0000 |
parents | 5069a8a40b1b |
children | c27614f2dec1 |
comparison
equal
deleted
inserted
replaced
30414:5069a8a40b1b | 30415:e8fb03cfbbde |
---|---|
113 if p: | 113 if p: |
114 pids.remove(p) | 114 pids.remove(p) |
115 st = _exitstatus(st) | 115 st = _exitstatus(st) |
116 if st and not problem[0]: | 116 if st and not problem[0]: |
117 problem[0] = st | 117 problem[0] = st |
118 # unregister SIGCHLD handler as all children will be killed | |
119 signal.signal(signal.SIGCHLD, oldchldhandler) | |
118 killworkers() | 120 killworkers() |
121 def sigchldhandler(signum, frame): | |
122 waitforworkers(blocking=False) | |
123 oldchldhandler = signal.signal(signal.SIGCHLD, sigchldhandler) | |
119 for pargs in partition(args, workers): | 124 for pargs in partition(args, workers): |
120 pid = os.fork() | 125 pid = os.fork() |
121 if pid == 0: | 126 if pid == 0: |
122 signal.signal(signal.SIGINT, oldhandler) | 127 signal.signal(signal.SIGINT, oldhandler) |
128 signal.signal(signal.SIGCHLD, oldchldhandler) | |
123 try: | 129 try: |
124 os.close(rfd) | 130 os.close(rfd) |
125 for i, item in func(*(staticargs + (pargs,))): | 131 for i, item in func(*(staticargs + (pargs,))): |
126 os.write(wfd, '%d %s\n' % (i, item)) | 132 os.write(wfd, '%d %s\n' % (i, item)) |
127 os._exit(0) | 133 os._exit(0) |
135 t = threading.Thread(target=waitforworkers) | 141 t = threading.Thread(target=waitforworkers) |
136 t.start() | 142 t.start() |
137 def cleanup(): | 143 def cleanup(): |
138 signal.signal(signal.SIGINT, oldhandler) | 144 signal.signal(signal.SIGINT, oldhandler) |
139 t.join() | 145 t.join() |
146 signal.signal(signal.SIGCHLD, oldchldhandler) | |
140 status = problem[0] | 147 status = problem[0] |
141 if status: | 148 if status: |
142 if status < 0: | 149 if status < 0: |
143 os.kill(os.getpid(), -status) | 150 os.kill(os.getpid(), -status) |
144 sys.exit(status) | 151 sys.exit(status) |