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
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to