X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=Control%2FException.hs;h=c573e3a7fe6025084b7c907cc9b79bd96b1e81be;hb=4748a7927948a6538c6e96a3d06bea75545b9301;hp=9e7a4c9d9c61a6519beae5861b036bc46c8c913b;hpb=1036239c803239aea8529e6f5020b0c8e37c5dba;p=ghc-base.git diff --git a/Control/Exception.hs b/Control/Exception.hs index 9e7a4c9..c573e3a 100644 --- a/Control/Exception.hs +++ b/Control/Exception.hs @@ -53,8 +53,8 @@ module Control.Exception ( System.ExitCode(), -- instance Exception #endif - BlockedOnDeadMVar(..), - BlockedIndefinitely(..), + BlockedIndefinitelyOnMVar(..), + BlockedIndefinitelyOnSTM(..), Deadlock(..), NoMethodError(..), PatternMatchFail(..), @@ -104,14 +104,25 @@ module Control.Exception ( -- ** 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 @@ -138,7 +149,6 @@ import Control.Exception.Base #ifdef __GLASGOW_HASKELL__ import GHC.Base -import GHC.IOBase import Data.Maybe #else import Prelude hiding (catch) @@ -243,20 +253,19 @@ easy to introduce race conditions by the over zealous use of -} {- $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. @@ -268,8 +277,9 @@ recovering from an asynchronous exception. {- $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'), @@ -277,11 +287,10 @@ and most operations which perform 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