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 |