Final bikeshedding call: Fixing Control.Exception.bracket

Yuras Shumovich shumovichy at gmail.com
Thu Nov 13 11:34:30 UTC 2014


On Thu, 2014-11-13 at 10:58 +0000, Simon Marlow wrote:
> On 11/11/2014 23:28, Yuras Shumovich wrote:
> >
> > The correct cleanup probably should look like the next:
> >
> > closeDB (DB h1 h2) = hClose h1 `finally` hClose h2
> >
> > Note: the initial version is buggy with respect to both async and sync
> > exceptions, and uninterruptibleMask will fix it only with respect to
> > async exceptions.
> 
> But in order to know that this is correct, you have to know how hClose 
> works, namely that if an async exception is raised then it has safely 
> closed the handle anyway.

hClose should mention that in it's contract. And I believe it should
mention *any* behavior it implements.

>   If you didn't know that, then you would have 
> to code it like this instead
> 
> closeDB (DB h1 h2) = cleanup1
>    where
>    cleanup1 = (hClose h1 `onException` cleanup1) >> cleanup2
>    cleanup2 = hClose h2 `onException` cleanup2
> 
> Does this really work?  I think so, but I haven't tested it...
> 
> I think your point about async exceptions under mask just being a 
> special case of sync exceptions is a good one, though.  I'm now 
> wondering whether maybe the right solution is to make it easier to use 
> the idiom in the above code.

But actually it is not *my* point, that is stated by Control.Exception
docs about interruptible actions:

>  In many cases these operations may themselves raise exceptions, such
as I/O errors, so the caller will usually be prepared to handle
exceptions arising from the operation anyway

Thanks,
Yuras



More information about the Libraries mailing list