
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. Cheers, Bertram