
On Thu, Oct 14, 2010 at 10:20 AM, Michael Snoyman
Did you have particular reasons why you thought the resources would not be freed correctly Antoine? I'd love any insight you have on this.
I didn't have a good reason at the time, but your email above crystallized it for me - it's that that the MonadCatchIO package doesn't provide the things I need as primitives. Here's my implementation of allocaBytes:
allocaBytes :: (MonadCatchIO m) => Int -> (Ptr a -> m b) -> m b allocaBytes size = bracket (liftIO $ F.mallocBytes size) (liftIO . F.free)
As you've described above, if someone is using this in ErrorT (or even MaybeT) I can't promise that F.free is ever run:
bracket :: MonadCatchIO m => m a -> (a -> m b) -> (a -> m c) -> m c bracket before after thing = block (do a <- before r <- unblock (thing a) `onException` after a _void $ after a return r)
Because the 'do' runs in 'ErrorT', then nothing promises that the line "_void $ after a" is run. If there are one or two primitives we can add to MonadCatchIO to make it so bracket and finally can be implemented safely I'm all for it. Maybe the simple thing is to just lift them all into the class, but I'm hoping there is a better way to describe what we want. Antoine