From: Bas van Dijk Date: Sun, 26 Sep 2010 19:21:44 +0000 (+0000) Subject: Add throwSTM :: Exception e => e -> STM a X-Git-Tag: ghc-darcs-git-switchover~104 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=d71ca65be98abb12afa1dfc2815e6e157799ffdc;hp=0b899bbe17a448fa5f96d2c24ff198bd29ef6e61;p=ghc-base.git Add throwSTM :: Exception e => e -> STM a --- diff --git a/GHC/Conc.lhs b/GHC/Conc.lhs index d08ccf2..47b6ef6 100644 --- a/GHC/Conc.lhs +++ b/GHC/Conc.lhs @@ -58,6 +58,7 @@ module GHC.Conc , atomically -- :: STM a -> IO a , retry -- :: STM a , orElse -- :: STM a -> STM a -> STM a + , throwSTM -- :: Exception e => e -> STM a , catchSTM -- :: Exception e => STM a -> (e -> STM a) -> STM a , alwaysSucceeds -- :: STM a -> STM () , always -- :: STM Bool -> STM () diff --git a/GHC/Conc/Sync.lhs b/GHC/Conc/Sync.lhs index 38717e6..b00c851 100644 --- a/GHC/Conc/Sync.lhs +++ b/GHC/Conc/Sync.lhs @@ -52,6 +52,7 @@ module GHC.Conc.Sync , atomically -- :: STM a -> IO a , retry -- :: STM a , orElse -- :: STM a -> STM a -> STM a + , throwSTM -- :: Exception e => e -> STM a , catchSTM -- :: Exception e => STM a -> (e -> STM a) -> STM a , alwaysSucceeds -- :: STM a -> STM () , always -- :: STM Bool -> STM () @@ -509,6 +510,27 @@ retry = STM $ \s# -> retry# s# orElse :: STM a -> STM a -> STM a orElse (STM m) e = STM $ \s -> catchRetry# m (unSTM e) s +-- | A variant of 'throw' that can only be used within the 'STM' monad. +-- +-- Throwing an exception in @STM@ aborts the transaction and propagates the +-- exception. +-- +-- Although 'throwSTM' has a type that is an instance of the type of 'throw', the +-- two functions are subtly different: +-- +-- > throw e `seq` x ===> throw e +-- > throwSTM e `seq` x ===> x +-- +-- The first example will cause the exception @e@ to be raised, +-- whereas the second one won\'t. In fact, 'throwSTM' will only cause +-- an exception to be raised when it is used within the 'STM' monad. +-- The 'throwSTM' variant should be used in preference to 'throw' to +-- raise an exception within the 'STM' monad because it guarantees +-- ordering with respect to other 'STM' operations, whereas 'throw' +-- does not. +throwSTM :: Exception e => e -> STM a +throwSTM e = STM $ raiseIO# (toException e) + -- |Exception handling within STM actions. catchSTM :: Exception e => STM a -> (e -> STM a) -> STM a catchSTM (STM m) handler = STM $ catchSTM# m handler'