
On 10/11/2010 17:52, Mitar wrote:
Hi!
On Wed, Nov 10, 2010 at 4:16 PM, Simon Marlow
wrote: The right way to fix it is like this:
Optimist. ;-)
let run = unblock doSomething `catches` [ Handler (\(_ :: MyTerminateException) -> return ()), Handler (\(e :: SomeException) -> putStrLn $ "Exception: " ++ show e) ] `finally` (putMVar terminated ()) nid<- block $ forkIO run
In 6.12.3 this does not work (it does not change anything, I hope I tested it correctly) because finally is defined as:
a `finally` sequel = block (do r<- unblock a `onException` sequel _<- sequel return r )
Oh, good point! I must have tested it with 7.0. So this is indeed something that is fixed by the new async exceptions API: finally itself doesn't raise async exceptions inside a mask. To fix this with GHC 6.12.3 you'd have to avoid finally and do it manually: let run = do r <- (unblock doSomething `catches` [ Handler (\(_ :: MyTerminateException) -> return ()), Handler (\(e :: SomeException) -> putStrLn $ "Exception: " ++ show e) ]) `onException` sequel sequel where sequel = putMVar terminated () Now *that* works - I tested it with 6.12.3 this time. Cheers, Simon
You see that unblock there? So it still unblocks so that second exception is delivered immediately after catches handles the first exception?
But I agree that your explanation for what is happening is the correct one. Better than my "hanging threads at the end". And with my throwIO approach I just override MyTerminateException with ThreadKilled.
Mitar