summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Denhardt <ian@zenhack.net>2018-10-26 18:05:05 -0400
committerBen Gamari <ben@smart-cactus.org>2018-10-29 15:11:47 -0400
commit503ddd6ede3e54748360f86ed744dcef0be71a28 (patch)
tree09d8380a8697e9a6ee82bd0b130b92edbf1e1a76
parent44a1d1f6612e1e9ef07626e1d2536bb6ba55dbd2 (diff)
downloadhaskell-503ddd6ede3e54748360f86ed744dcef0be71a28.tar.gz
Docs: clarify the interaction between throwSTM and catchSTM.
The previous doc comments were not terribly clear on what was or wasn't rolled back when an exception was caught in STM. This misunderstanding was the source of a bug in another project of mine, and folks on `#haskell` found it confusing as well.
-rw-r--r--libraries/base/GHC/Conc/Sync.hs14
1 files changed, 12 insertions, 2 deletions
diff --git a/libraries/base/GHC/Conc/Sync.hs b/libraries/base/GHC/Conc/Sync.hs
index 6751de72a8..7038b0db04 100644
--- a/libraries/base/GHC/Conc/Sync.hs
+++ b/libraries/base/GHC/Conc/Sync.hs
@@ -752,7 +752,12 @@ 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.
+-- exception. If the exception is caught via 'catchSTM', only the changes
+-- enclosed by the catch are rolled back; changes made outside of 'catchSTM'
+-- persist.
+--
+-- If the exception is not caught inside of the 'STM', it is re-thrown by
+-- 'atomically', and the entire 'STM' is rolled back.
--
-- Although 'throwSTM' has a type that is an instance of the type of 'throw', the
-- two functions are subtly different:
@@ -770,7 +775,12 @@ orElse (STM m) e = STM $ \s -> catchRetry# m (unSTM e) s
throwSTM :: Exception e => e -> STM a
throwSTM e = STM $ raiseIO# (toException e)
--- |Exception handling within STM actions.
+-- | Exception handling within STM actions.
+--
+-- @'catchSTM' m f@ catches any exception thrown by @m@ using 'throwSTM',
+-- using the function @f@ to handle the exception. If an exception is
+-- thrown, any changes made by @m@ are rolled back, but changes prior to
+-- @m@ persist.
catchSTM :: Exception e => STM a -> (e -> STM a) -> STM a
catchSTM (STM m) handler = STM $ catchSTM# m handler'
where