id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,os,architecture,failure,difficulty,testcase,blockedby,blocking,related
4400,Asynchronous exceptions in runInUnboundThread,basvandijk,simonmar,"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.) 
",proposal,closed,high,7.4.1,libraries/base,6.12.3,fixed,,,Unknown/Multiple,Unknown/Multiple,None/Unknown,,,,,
