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