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)