Asynchronous exceptions in runInUnboundThread
When you throw an asynchronous exception to a thread which is executing: runInUnboundThread m, m will keep executing and there's no way to kill it.
I propose to catch asynchronous exceptions in runInUnboundThread and throw them to the thread which is executing m. m in turn can decide to catch or ignore them. In case m decides to ignore them or to rethrow them, the exception will be rethrown in the current thread:
runInUnboundThread :: IO a -> IO a
runInUnboundThread action = do
bound <- isCurrentThreadBound
if bound
then do
mv <- newEmptyMVar
mask $ \restore -> do
tid <- forkIO $ Exception.try (restore action) >>= putMVar mv
let wait = takeMVar mv `Exception.catch` \(e :: SomeException) ->
Exception.throwTo tid e >> wait
wait >>= unsafeResult
else action
unsafeResult :: Either SomeException a -> IO a
unsafeResult = either Exception.throwIO return
The attached patch implements this behaviour.
(Note there are two other bug-fix patches in the bundle that this patch depends on which can be independently applied.)
Trac metadata
| Trac field | Value |
|---|---|
| Version | 6.12.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |