summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Martin <andrew.thaddeus@gmail.com>2017-11-18 14:43:20 -0500
committerBen Gamari <ben@smart-cactus.org>2017-11-18 14:44:23 -0500
commitb8e324a4ff7d04d55dc8d8d8b9e441225c9dd4f6 (patch)
treef1f2a7ca0321422147b3f3528cee179f964ff5be
parent912a72d2241402d23ce7326021fd143f2739da82 (diff)
downloadhaskell-b8e324a4ff7d04d55dc8d8d8b9e441225c9dd4f6.tar.gz
base: Make documentation of atomically more accurate
-rw-r--r--libraries/base/GHC/Conc/Sync.hs23
1 files changed, 16 insertions, 7 deletions
diff --git a/libraries/base/GHC/Conc/Sync.hs b/libraries/base/GHC/Conc/Sync.hs
index 06da99b7d2..de7779291f 100644
--- a/libraries/base/GHC/Conc/Sync.hs
+++ b/libraries/base/GHC/Conc/Sync.hs
@@ -716,13 +716,22 @@ unsafeIOToSTM (IO m) = STM m
-- | Perform a series of STM actions atomically.
--
--- You cannot use 'atomically' inside an 'unsafePerformIO' or 'unsafeInterleaveIO'.
--- Any attempt to do so will result in a runtime error. (Reason: allowing
--- this would effectively allow a transaction inside a transaction, depending
--- on exactly when the thunk is evaluated.)
---
--- However, see 'newTVarIO', which can be called inside 'unsafePerformIO',
--- and which allows top-level TVars to be allocated.
+-- Using 'atomically' inside an 'unsafePerformIO' or 'unsafeInterleaveIO'
+-- subverts some of guarantees that STM provides. It makes it possible to
+-- run a transaction inside of another transaction, depending on when the
+-- thunk is evaluated. If a nested transaction is attempted, an exception
+-- is thrown by the runtime. It is possible to safely use 'atomically' inside
+-- 'unsafePerformIO' or 'unsafeInterleaveIO', but the typechecker does not
+-- rule out programs that may attempt nested transactions, meaning that
+-- the programmer must take special care to prevent these.
+--
+-- However, there are functions for creating transactional variables that
+-- can always be safely called in 'unsafePerformIO'. See: 'newTVarIO',
+-- 'newTChanIO', 'newBroadcastTChanIO', 'newTQueueIO', 'newTBQueueIO',
+-- and 'newTMVarIO'.
+--
+-- Using 'unsafePerformIO' inside of 'atomically' is also dangerous but for
+-- different reasons. See 'unsafeIOToSTM' for more on this.
atomically :: STM a -> IO a
atomically (STM m) = IO (\s -> (atomically# m) s )