[Haskell-cafe] ResourceT "unmasked" during allocation?

Viktor Dukhovni ietf-dane at dukhovni.org
Mon Nov 7 00:30:59 UTC 2016

I am looking at using ResourceT to manage the acquisiition and
deallocation of network sockets.  In comparing resourceT's `allocate`
with `bracket` I was somewhat perplexed to find that `allocate` in
Control.Monad.Trans.Resource seems to not mask exceptions during
allocation (see "No mask" comment I inserted):

	allocateRIO :: IO a -> (a -> IO ()) -> ResourceT IO (ReleaseKey, a)
	allocateRIO acquire rel = ResourceT $ \istate -> liftIO $ E.mask $ \restore -> do
	    a <- restore acquire
            --   ^^^ No mask ^^^
	    key <- register' istate $ rel a
	    return (key, a)

	allocate :: MonadResource m
		 => IO a -- ^ allocate
		 -> (a -> IO ()) -- ^ free resource
		 -> m (ReleaseKey, a)
	allocate a = liftResourceT . allocateRIO a

By contrast in Exception.Base we see that `bracket` masks
the initialization action:

	bracket before after thing =
	  mask $ \restore -> do
	    a <- before
            --   ^^^ masked! ^^^
	    r <- restore (thing a) `onException` after a
	    _ <- after a
	    return r

This seems to suggest that ResourceT is more exposes to resource
leaks via asynchronous exceptions.  Say if a file descriptor is a
allocated, but an exception interrupts "allocate" before it can
register the resource.

Perhaps I am missing something, or there are good reasons for
the difference in approach.  Can anyone shed some light on the
reason why ResourceT differs (seemingly) from bracket in this


More information about the Haskell-Cafe mailing list