[Haskell-cafe] ANNOUNCE: iterIO-0.1 - iteratee-based IO with pipe operators

dm-list-haskell-cafe at scs.stanford.edu dm-list-haskell-cafe at scs.stanford.edu
Wed May 11 18:56:51 CEST 2011

At Wed, 11 May 2011 13:02:21 +0100,
Simon Marlow wrote:
> There's no guarantee of the form that you mention - asynchronous 
> exceptions can occur anywhere.  However, there might be a way to do what 
> you want (disclaimer: I haven't looked at the implementation of iterIO).
> Control.Exception will have a new operation in 7.2.1:
>    allowInterrupt :: IO ()
>    allowInterrupt = unsafeUnmask $ return ()
> which allows an asynchronous exception to be thrown inside mask (until 
> 7.2.1 you can define it yourself, unsafeUnmask comes from GHC.IO).

Ah.  I didn't know about unsafeUnmask.  Is unmaskAsyncExceptions# low
enough overhead that it would be reasonable to wrap every invocation
of liftIO in unsafeUnmask?

I'm now thinking it might be reasonable to execute all liftIO actions
inside unsafeUnmask (with maybe a special liftIOmasked function for
those few places where you don't want asynchronous exceptions).  Most
of the uses of mask are because you need two or more binds to execute
without interruption, e.g.:

	bracket before after thing =
	  mask $ \restore -> do
	    a <- before
	-- Big problem if exception happens here --
	    r <- restore (thing a) `onException` after a
	    _ <- after a
	    return r

But when bind sites are the only place an exception can be thrown,
things get a lot simpler.  For instance, it is perfectly reasonable to

	bracket before after thing = do
	  a <- before
	  thing a `finallyI` after a


More information about the Haskell-Cafe mailing list