@@ -181,9 +181,6 @@ runAsPID1 cmd args env' timeout = do
181
181
-- children processes. Then start a thread waiting for that
182
182
-- variable to be filled and do the actual killing.
183
183
killChildrenVar <- newEmptyMVar
184
- _ <- forkIO $ do
185
- takeMVar killChildrenVar
186
- killAllChildren timeout
187
184
188
185
-- Helper function to start killing, used below
189
186
let startKilling = void $ tryPutMVar killChildrenVar ()
@@ -206,6 +203,10 @@ runAsPID1 cmd args env' timeout = do
206
203
ClosedHandle e -> assert False (exitWith e)
207
204
OpenHandle pid -> return pid
208
205
206
+ _ <- forkIO $ do
207
+ takeMVar killChildrenVar
208
+ killAllChildren child timeout
209
+
209
210
-- Loop on reaping child processes
210
211
reap startKilling child
211
212
@@ -247,9 +248,20 @@ reap startKilling child = do
247
248
startKilling
248
249
| otherwise -> return ()
249
250
250
- killAllChildren :: Int -> IO ()
251
- killAllChildren timeout = do
252
- -- Send all children processes the TERM signal
251
+ killAllChildren :: CPid -> Int -> IO ()
252
+ killAllChildren cid timeout = do
253
+ -- Send the direct child process the TERM signal
254
+ signalProcess sigTERM cid `catch` \ e ->
255
+ if isDoesNotExistError e
256
+ then return ()
257
+ else throwIO e
258
+
259
+ -- Wait for `timeout` seconds and allow the 'main' process to take care
260
+ -- of shutting down any child processes itself.
261
+ threadDelay $ timeout * 1000 * 1000
262
+
263
+ -- If the 'main' process did not handle shutting down the rest of the
264
+ -- child processes we will signal SIGTERM to them directly.
253
265
signalProcess sigTERM (- 1 ) `catch` \ e ->
254
266
if isDoesNotExistError e
255
267
then return ()
0 commit comments