Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception

Bertram Felgenhauer bertram.felgenhauer at
Sat Sep 6 19:03:15 UTC 2014

Eyal Lotem wrote:
> The problem with requiring the user to use uninterruptibleMask_ on their
> cleanup is how error-prone it is.
> If we examine some uses of bracket in the GHC repo:
> compiler/main/GhcMake.hs:992:        let withSem sem = bracket_ (waitQSem
> sem) (*signalQSem sem*)
> *signalQSem is interruptible, this is a bug!*

Not really, but signalQSem is a rare exception from the rule.

signalQSem :: QSem -> IO ()
signalQSem (QSem m) =
  uninterruptibleMask_ $ do -- Note [signal uninterruptible]
    r <- takeMVar m
    r' <- signal r
    putMVar m r'

It's tempting to suggest that every cleanup type function should just
mask exceptions itself like this. However, that does not solve the
problem when several cleanup actions are required: at the end of the
first uninterruptibleMask_, any pending exceptions will be delivered.

Overall I agree with your assessment that a general uninterruptibleMask_
for cleanup handlers avoids more trouble than it causes.



More information about the Libraries mailing list