diff options
author | Ian Denhardt <ian@zenhack.net> | 2018-10-26 18:05:05 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-10-29 15:11:47 -0400 |
commit | 503ddd6ede3e54748360f86ed744dcef0be71a28 (patch) | |
tree | 09d8380a8697e9a6ee82bd0b130b92edbf1e1a76 | |
parent | 44a1d1f6612e1e9ef07626e1d2536bb6ba55dbd2 (diff) | |
download | haskell-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.hs | 14 |
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 |