
#12038: Shutdown interacts badly with requestSync() -------------------------------------+------------------------------------- Reporter: simonmar | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.2.1 Component: Runtime System | Version: 7.10.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Description changed by simonmar: @@ -0,0 +1,3 @@ + I've been investigating #10860, and the problem goes pretty deep, + so I'm going to record what I know here and come back to fix it + properly later. @@ -2,0 +5,19 @@ + We have this mechanism `requestSync()` for operations that need + to seize control of the whole runtime to do something. It is used by + + * `scheduleDoGC()` + * `setNumCapabilities()` + * `forkProcess()` + + `requestSync()` ensures that only one of these operations wins, + the others will `yieldCapability()` to the winner, before + continuing with their own sync. + + The problem is that this interacts badly with shutdown. Shutdown + might start at any time (initiated by `exitScheduler()`). If it + starts during a sync, then a deadlock is likely: some + capabilities will be already shut down, and cannot be acquired by + `acquireAllCapabilities()`. This happens in #10860. + + Really, shutdown should play the `requestSync()` game too, but + that requires a lot of thought. New description: I've been investigating #10860, and the problem goes pretty deep, so I'm going to record what I know here and come back to fix it properly later. We have this mechanism `requestSync()` for operations that need to seize control of the whole runtime to do something. It is used by * `scheduleDoGC()` * `setNumCapabilities()` * `forkProcess()` `requestSync()` ensures that only one of these operations wins, the others will `yieldCapability()` to the winner, before continuing with their own sync. The problem is that this interacts badly with shutdown. Shutdown might start at any time (initiated by `exitScheduler()`). If it starts during a sync, then a deadlock is likely: some capabilities will be already shut down, and cannot be acquired by `acquireAllCapabilities()`. This happens in #10860. Really, shutdown should play the `requestSync()` game too, but that requires a lot of thought. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12038#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler