System.ExitCode(), -- instance Exception
#endif
- BlockedOnDeadMVar(..),
- BlockedIndefinitely(..),
+ BlockedIndefinitelyOnMVar(..),
+ BlockedIndefinitelyOnSTM(..),
Deadlock(..),
NoMethodError(..),
PatternMatchFail(..),
-- ** Asynchronous exception control
- -- |The following two functions allow a thread to control delivery of
+ -- |The following functions allow a thread to control delivery of
-- asynchronous exceptions during a critical region.
+ mask,
+#ifndef __NHC__
+ mask_,
+ uninterruptibleMask,
+ uninterruptibleMask_,
+ MaskingState(..),
+ getMaskingState,
+#endif
+
+ -- ** (deprecated) Asynchronous exception control
+
block,
unblock,
blocked,
- -- *** Applying @block@ to an exception handler
+ -- *** Applying @mask@ to an exception handler
-- $block_handler
#ifdef __GLASGOW_HASKELL__
import GHC.Base
-import GHC.IOBase
import Data.Maybe
#else
import Prelude hiding (catch)
-}
{- $block_handler
-There\'s an implied 'block' around every exception handler in a call
+There\'s an implied 'mask' around every exception handler in a call
to one of the 'catch' family of functions. This is because that is
what you want most of the time - it eliminates a common race condition
in starting an exception handler, because there may be no exception
handler on the stack to handle another exception if one arrives
-immediately. If asynchronous exceptions are blocked on entering the
+immediately. If asynchronous exceptions are masked on entering the
handler, though, we have time to install a new exception handler
before being interrupted. If this weren\'t the default, one would have
to write something like
-> block (
-> catch (unblock (...))
-> (\e -> handler)
-> )
+> mask $ \restore ->
+> catch (restore (...))
+> (\e -> handler)
If you need to unblock asynchronous exceptions again in the exception
-handler, just use 'unblock' as normal.
+handler, 'restore' can be used there too.
Note that 'try' and friends /do not/ have a similar default, because
there is no exception handler in this case. Don't use 'try' for
{- $interruptible
+ #interruptible#
Some operations are /interruptible/, which means that they can receive
-asynchronous exceptions even in the scope of a 'block'. Any function
+asynchronous exceptions even in the scope of a 'mask'. Any function
which may itself block is defined as interruptible; this includes
'Control.Concurrent.MVar.takeMVar'
(but not 'Control.Concurrent.MVar.tryTakeMVar'),
some I\/O with the outside world. The reason for having
interruptible operations is so that we can write things like
-> block (
+> mask $ \restore -> do
> a <- takeMVar m
-> catch (unblock (...))
+> catch (restore (...))
> (\e -> ...)
-> )
if the 'Control.Concurrent.MVar.takeMVar' was not interruptible,
then this particular