Final bikeshedding call: Fixing Control.Exception.bracket

Simon Marlow marlowsd at gmail.com
Sun Nov 23 15:08:50 UTC 2014


On 21/11/14 17:22, Gregory Collins wrote:
> New post from Yuras provides food for thought:
> https://github.com/Yuras/io-region/wiki/Handling-%28async%29-exceptions-in-haskell:-pushing-bracket-to-the-limits
>
> In particular he points out a case for which uninterruptibleMask will
> cause unkillable threads: let's say hClose blocks flushing the output to
> a file, but the write fails because of a hardware error and blocks
> forever. (Alternatively, imagine the file is on NFS and you get a cable
> cut between the two machines). The thread executing hClose in the
> cleanup action becomes unkillable.

Yes, and furthermore hClose is not "buggy": even if it is interrupted by 
an async exception, the file descriptor will still be closed by the 
finalizer.  This is not something you want to do a lot, of course, but 
as a backup plan for the rare case of an async exception killing the 
cleanup action it's fine.

So arguably uninterruptibleMask is not what we want for hClose.

Cheers,
Simon


> G
>
> On Thu, Nov 20, 2014 at 7:24 AM, Simon Marlow <marlowsd at gmail.com
> <mailto:marlowsd at gmail.com>> wrote:
>
>     On 19/11/2014 23:07, Ganesh Sittampalam wrote:
>
>         On 13/11/2014 10:44, Simon Marlow wrote:
>
>             On 13/11/2014 07:47, Merijn Verstraaten wrote:
>
>
>                 A new version would look like:
>
>                 bracket before after thing =
>                      mask $ \restore -> do
>                        let atomicAfter = uninterruptibleMask . after
>                        a <- before
>                        r <- restore (thing a) `onException` atomicAfter a
>                        _ <- atomicAfter a
>                        return r
>
>                 Slightly different versions are possible and the other
>                 relevant
>                 bracketing functions mentioned in this thread can be
>                 treated similarly.
>
>
>             Since we would need this for catch too, the sensible thing
>             to do (if we
>             decide to go ahead with this) would be to change the
>             implementation of
>             catch in the RTS from masking the exception handler to
>             uninterruptibleMask.  That would mean that at least for
>             catch there
>             would be no additional overhead, and it would make the
>             modifications to
>             the other operations simpler in some cases.
>
>
>         If this isn't done in the RTS, is there a possibility of an async
>         exception slipping in between the exception handler starting and the
>         uninterruptibleMask starting?
>
>
>     No, because the exception handler is masked.
>
>     Cheers,
>     Simon
>
>     _________________________________________________
>     Libraries mailing list
>     Libraries at haskell.org <mailto:Libraries at haskell.org>
>     http://www.haskell.org/__mailman/listinfo/libraries
>     <http://www.haskell.org/mailman/listinfo/libraries>
>
>
>
>
> --
> Gregory Collins <greg at gregorycollins.net <mailto:greg at gregorycollins.net>>



More information about the Libraries mailing list