[GHC] #9516: unsafeUnmask unmasks even inside uninterruptibleMask

GHC ghc-devs at haskell.org
Wed Aug 27 10:54:46 UTC 2014


#9516: unsafeUnmask unmasks even inside uninterruptibleMask
-------------------------------------+-------------------------------------
       Reporter:  edsko              |                   Owner:  simonmar
           Type:  bug                |                  Status:  new
       Priority:  normal             |               Milestone:
      Component:  Runtime System     |                 Version:  7.8.2
       Keywords:                     |        Operating System:
   Architecture:  Unknown/Multiple   |  Unknown/Multiple
     Difficulty:  Unknown            |         Type of failure:
     Blocked By:                     |  None/Unknown
Related Tickets:                     |               Test Case:
                                     |                Blocking:
                                     |  Differential Revisions:
-------------------------------------+-------------------------------------
 Control.Exception exports

 {{{#!hs
 allowInterrupt :: IO ()
 allowInterrupt = unsafeUnmask $ return ()
 }}}

 with documentation:

 ''When invoked inside `mask`, this function allows a blocked asynchronous
 exception to be raised, if one exists. It is equivalent to performing an
 interruptible operation, but does not involve any actual blocking. When
 called outside `mask`, or inside `uninterruptibleMask`, this function has
 no effect.''

 However, this is not actually true: `unsafeUnmask` unmasks exceptions even
 inside `uninterruptibleUnmask`, as the attached test demonstrates (the
 test uses a foreign call just to have something non-interruptible but
 still observable; in particular, doing a `print` ''is'' interruptible
 because it uses an `MVar` under the hood).

 I think it is possible to define a better `unsafeUnmask` in user-land:

 {{{#!hs
 interruptible :: IO a -> IO a
 interruptible act = do
   st <- getMaskingState
   case st of
     Unmasked              -> act
     MaskedInterruptible   -> unsafeUnmask act
     MaskedUninterruptible -> act
 }}}

 but it still seems to be that we should either (i) change the behaviour of
 unsafeUnmask, or (ii) provide a version of `unsafeUnmask` with the
 behaviour as described and then change `allowInterrupt` to use that new
 version of `unsafeUnmask`, or at the very least (iii) change the
 documentation.

 (One question with the above definition of `interruptible` is what happens
 when we ''nest'' `mask` and `uninterruptibleMask`?)

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9516>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list