
Bas van Dijk wrote:
... However now comes the problem I would like to talk about. What if I want to use modifyMVar_ as part of a bigger atomic transaction. As in:
block $ do ... modifyMVar_ m f ...
From a quick glanse at this code it looks like asynchronous exceptions can't be thrown to this transaction because we block them. However the unblock in modifyMVar_ opens an asynchronous exception "wormhole" right into our blocked computation. This destroys modularity.
Would it work if 'block' adds a layer of blocking and 'unblock' removes one layer of blocking? So block a = do modifyIORef blockLevel (+1) result <- a modifyIORef blockLevel (-1) return result unblock a = do modifyIORef blockLevel (-1) result <- a modifyIORef blockLevel (+1) return result canThrowExceptions = (<= 0) `liftM` readIORef blockLevel Although it is probably a better idea to not use block/unblock at all in user code. Twan