Split up coercionKind
[ghc.git] / libraries / base / Control / Concurrent / MVar.hs
1 {-# LANGUAGE Trustworthy #-}
2 {-# LANGUAGE NoImplicitPrelude, UnboxedTuples, MagicHash #-}
3
4 -----------------------------------------------------------------------------
5 -- |
6 -- Module : Control.Concurrent.MVar
7 -- Copyright : (c) The University of Glasgow 2001
8 -- License : BSD-style (see the file libraries/base/LICENSE)
9 --
10 -- Maintainer : libraries@haskell.org
11 -- Stability : experimental
12 -- Portability : non-portable (concurrency)
13 --
14 -- An @'MVar' t@ is mutable location that is either empty or contains a
15 -- value of type @t@. It has two fundamental operations: 'putMVar'
16 -- which fills an 'MVar' if it is empty and blocks otherwise, and
17 -- 'takeMVar' which empties an 'MVar' if it is full and blocks
18 -- otherwise. They can be used in multiple different ways:
19 --
20 -- 1. As synchronized mutable variables,
21 --
22 -- 2. As channels, with 'takeMVar' and 'putMVar' as receive and send, and
23 --
24 -- 3. As a binary semaphore @'MVar' ()@, with 'takeMVar' and 'putMVar' as
25 -- wait and signal.
26 --
27 -- They were introduced in the paper
28 -- <https://www.haskell.org/ghc/docs/papers/concurrent-haskell.ps.gz "Concurrent Haskell">
29 -- by Simon Peyton Jones, Andrew Gordon and Sigbjorn Finne, though
30 -- some details of their implementation have since then changed (in
31 -- particular, a put on a full 'MVar' used to error, but now merely
32 -- blocks.)
33 --
34 -- === Applicability
35 --
36 -- 'MVar's offer more flexibility than 'Data.IORef.IORef's, but less flexibility
37 -- than 'GHC.Conc.STM'. They are appropriate for building synchronization
38 -- primitives and performing simple interthread communication; however
39 -- they are very simple and susceptible to race conditions, deadlocks or
40 -- uncaught exceptions. Do not use them if you need perform larger
41 -- atomic operations such as reading from multiple variables: use 'GHC.Conc.STM'
42 -- instead.
43 --
44 -- In particular, the "bigger" functions in this module ('swapMVar',
45 -- 'withMVar', 'modifyMVar_' and 'modifyMVar') are simply
46 -- the composition of a 'takeMVar' followed by a 'putMVar' with
47 -- exception safety.
48 -- These only have atomicity guarantees if all other threads
49 -- perform a 'takeMVar' before a 'putMVar' as well; otherwise, they may
50 -- block.
51 --
52 -- === Fairness
53 --
54 -- No thread can be blocked indefinitely on an 'MVar' unless another
55 -- thread holds that 'MVar' indefinitely. One usual implementation of
56 -- this fairness guarantee is that threads blocked on an 'MVar' are
57 -- served in a first-in-first-out fashion, but this is not guaranteed
58 -- in the semantics.
59 --
60 -- === Gotchas
61 --
62 -- Like many other Haskell data structures, 'MVar's are lazy. This
63 -- means that if you place an expensive unevaluated thunk inside an
64 -- 'MVar', it will be evaluated by the thread that consumes it, not the
65 -- thread that produced it. Be sure to 'evaluate' values to be placed
66 -- in an 'MVar' to the appropriate normal form, or utilize a strict
67 -- MVar provided by the strict-concurrency package.
68 --
69 -- === Ordering
70 --
71 -- 'MVar' operations are always observed to take place in the order
72 -- they are written in the program, regardless of the memory model of
73 -- the underlying machine. This is in contrast to 'Data.IORef.IORef' operations
74 -- which may appear out-of-order to another thread in some cases.
75 --
76 -- === Example
77 --
78 -- Consider the following concurrent data structure, a skip channel.
79 -- This is a channel for an intermittent source of high bandwidth
80 -- information (for example, mouse movement events.) Writing to the
81 -- channel never blocks, and reading from the channel only returns the
82 -- most recent value, or blocks if there are no new values. Multiple
83 -- readers are supported with a @dupSkipChan@ operation.
84 --
85 -- A skip channel is a pair of 'MVar's. The first 'MVar' contains the
86 -- current value, and a list of semaphores that need to be notified
87 -- when it changes. The second 'MVar' is a semaphore for this particular
88 -- reader: it is full if there is a value in the channel that this
89 -- reader has not read yet, and empty otherwise.
90 --
91 -- @
92 -- data SkipChan a = SkipChan (MVar (a, [MVar ()])) (MVar ())
93 --
94 -- newSkipChan :: IO (SkipChan a)
95 -- newSkipChan = do
96 -- sem <- newEmptyMVar
97 -- main <- newMVar (undefined, [sem])
98 -- return (SkipChan main sem)
99 --
100 -- putSkipChan :: SkipChan a -> a -> IO ()
101 -- putSkipChan (SkipChan main _) v = do
102 -- (_, sems) <- takeMVar main
103 -- putMVar main (v, [])
104 -- mapM_ (\sem -> putMVar sem ()) sems
105 --
106 -- getSkipChan :: SkipChan a -> IO a
107 -- getSkipChan (SkipChan main sem) = do
108 -- takeMVar sem
109 -- (v, sems) <- takeMVar main
110 -- putMVar main (v, sem:sems)
111 -- return v
112 --
113 -- dupSkipChan :: SkipChan a -> IO (SkipChan a)
114 -- dupSkipChan (SkipChan main _) = do
115 -- sem <- newEmptyMVar
116 -- (v, sems) <- takeMVar main
117 -- putMVar main (v, sem:sems)
118 -- return (SkipChan main sem)
119 -- @
120 --
121 -- This example was adapted from the original Concurrent Haskell paper.
122 -- For more examples of 'MVar's being used to build higher-level
123 -- synchronization primitives, see 'Control.Concurrent.Chan' and
124 -- 'Control.Concurrent.QSem'.
125 --
126 -----------------------------------------------------------------------------
127
128 module Control.Concurrent.MVar
129 (
130 -- * @MVar@s
131 MVar
132 , newEmptyMVar
133 , newMVar
134 , takeMVar
135 , putMVar
136 , readMVar
137 , swapMVar
138 , tryTakeMVar
139 , tryPutMVar
140 , isEmptyMVar
141 , withMVar
142 , withMVarMasked
143 , modifyMVar_
144 , modifyMVar
145 , modifyMVarMasked_
146 , modifyMVarMasked
147 , tryReadMVar
148 , mkWeakMVar
149 , addMVarFinalizer
150 ) where
151
152 import GHC.MVar ( MVar(..), newEmptyMVar, newMVar, takeMVar, putMVar,
153 tryTakeMVar, tryPutMVar, isEmptyMVar, readMVar,
154 tryReadMVar
155 )
156 import qualified GHC.MVar
157 import GHC.Weak
158 import GHC.Base
159
160 import Control.Exception.Base
161
162 {-|
163 Take a value from an 'MVar', put a new value into the 'MVar' and
164 return the value taken. This function is atomic only if there are
165 no other producers for this 'MVar'.
166 -}
167 swapMVar :: MVar a -> a -> IO a
168 swapMVar mvar new =
169 mask_ $ do
170 old <- takeMVar mvar
171 putMVar mvar new
172 return old
173
174 {-|
175 'withMVar' is an exception-safe wrapper for operating on the contents
176 of an 'MVar'. This operation is exception-safe: it will replace the
177 original contents of the 'MVar' if an exception is raised (see
178 "Control.Exception"). However, it is only atomic if there are no
179 other producers for this 'MVar'.
180 -}
181 {-# INLINE withMVar #-}
182 -- inlining has been reported to have dramatic effects; see
183 -- http://www.haskell.org//pipermail/haskell/2006-May/017907.html
184 withMVar :: MVar a -> (a -> IO b) -> IO b
185 withMVar m io =
186 mask $ \restore -> do
187 a <- takeMVar m
188 b <- restore (io a) `onException` putMVar m a
189 putMVar m a
190 return b
191
192 {-|
193 Like 'withMVar', but the @IO@ action in the second argument is executed
194 with asynchronous exceptions masked.
195
196 @since 4.7.0.0
197 -}
198 {-# INLINE withMVarMasked #-}
199 withMVarMasked :: MVar a -> (a -> IO b) -> IO b
200 withMVarMasked m io =
201 mask_ $ do
202 a <- takeMVar m
203 b <- io a `onException` putMVar m a
204 putMVar m a
205 return b
206
207 {-|
208 An exception-safe wrapper for modifying the contents of an 'MVar'.
209 Like 'withMVar', 'modifyMVar' will replace the original contents of
210 the 'MVar' if an exception is raised during the operation. This
211 function is only atomic if there are no other producers for this
212 'MVar'.
213 -}
214 {-# INLINE modifyMVar_ #-}
215 modifyMVar_ :: MVar a -> (a -> IO a) -> IO ()
216 modifyMVar_ m io =
217 mask $ \restore -> do
218 a <- takeMVar m
219 a' <- restore (io a) `onException` putMVar m a
220 putMVar m a'
221
222 {-|
223 A slight variation on 'modifyMVar_' that allows a value to be
224 returned (@b@) in addition to the modified value of the 'MVar'.
225 -}
226 {-# INLINE modifyMVar #-}
227 modifyMVar :: MVar a -> (a -> IO (a,b)) -> IO b
228 modifyMVar m io =
229 mask $ \restore -> do
230 a <- takeMVar m
231 (a',b) <- restore (io a >>= evaluate) `onException` putMVar m a
232 putMVar m a'
233 return b
234
235 {-|
236 Like 'modifyMVar_', but the @IO@ action in the second argument is executed with
237 asynchronous exceptions masked.
238
239 @since 4.6.0.0
240 -}
241 {-# INLINE modifyMVarMasked_ #-}
242 modifyMVarMasked_ :: MVar a -> (a -> IO a) -> IO ()
243 modifyMVarMasked_ m io =
244 mask_ $ do
245 a <- takeMVar m
246 a' <- io a `onException` putMVar m a
247 putMVar m a'
248
249 {-|
250 Like 'modifyMVar', but the @IO@ action in the second argument is executed with
251 asynchronous exceptions masked.
252
253 @since 4.6.0.0
254 -}
255 {-# INLINE modifyMVarMasked #-}
256 modifyMVarMasked :: MVar a -> (a -> IO (a,b)) -> IO b
257 modifyMVarMasked m io =
258 mask_ $ do
259 a <- takeMVar m
260 (a',b) <- (io a >>= evaluate) `onException` putMVar m a
261 putMVar m a'
262 return b
263
264 {-# DEPRECATED addMVarFinalizer "use 'mkWeakMVar' instead" #-} -- deprecated in 7.6
265 addMVarFinalizer :: MVar a -> IO () -> IO ()
266 addMVarFinalizer = GHC.MVar.addMVarFinalizer
267
268 -- | Make a 'Weak' pointer to an 'MVar', using the second argument as
269 -- a finalizer to run when 'MVar' is garbage-collected
270 --
271 -- @since 4.6.0.0
272 mkWeakMVar :: MVar a -> IO () -> IO (Weak (MVar a))
273 mkWeakMVar m@(MVar m#) (IO f) = IO $ \s ->
274 case mkWeak# m# m f s of (# s1, w #) -> (# s1, Weak w #)