bracket has interruptible cleanup
I'm opening this as a documentation issue, though the discussion is really about "is this a doc issue or a broken function issue."
bracket function in
Control.Exception uses interruptible masking in its implementation. This means that, if a cleanup handler performs any blocking operations, it may be interrupted by an async exception. This violates the intended usage of
bracket. There is a far more thorough explanation and discussion of this issue available at:
In that issue, I was convinced that in
safe-exceptions (and later, in
unliftio) we should change the behavior of the
bracket function to use uninterruptible masking instead.
Proposed improvements or changes
I see three different changes that could be made:
Document the current behavior Users should be aware of the fact that
bracket is not masking async exceptions during blocking calls. Users can then protect themselves by either using an alternate function, or explicitly using
uninterruptibleMask_ in their cleanup handlers.
Change the behavior of
bracket I'm weakly in favor of this. I think the changed behavior is definitely the right one. However, I worry about backwards compatibility here, since switching to uninterruptible masking does have the potential to introduce very complex semantic bugs into existing code.
Add new functions Introduce functions like
bracketUninterruptible, and encourage their usage to be explicit. This could go along well with documentation, and could be accompanied by a warning or deprecation on
bracket. Overall, this seems like more trouble than it's worth, but I did want to mention it.
CC @chessai, who encouraged me to create this issue.