[project @ 2002-05-09 13:16:29 by simonmar]
[packages/base.git] / Control / Concurrent / CVar.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module : Control.Concurrent.CVar
4 -- Copyright : (c) The University of Glasgow 2001
5 -- License : BSD-style (see the file libraries/base/LICENSE)
6 --
7 -- Maintainer : libraries@haskell.org
8 -- Stability : experimental
9 -- Portability : non-portable
10 --
11 -- Channel variables are one-element channels.
12 --
13 -----------------------------------------------------------------------------
14
15 module Control.Concurrent.CVar
16 ( -- abstract
17 CVar
18 , newCVar -- :: IO (CVar a)
19 , writeCVar -- :: CVar a -> a -> IO ()
20 , readCVar -- :: CVar a -> IO a
21 ) where
22
23 import Prelude
24
25 import Control.Concurrent.MVar
26
27 -- @MVars@ provide the basic mechanisms for synchronising access to a
28 -- shared resource. @CVars@, or channel variables, provide an abstraction
29 -- that guarantee that the producer is not allowed to run riot, but
30 -- enforces the interleaved access to the channel variable,i.e., a
31 -- producer is forced to wait up for a consumer to remove the previous
32 -- value before it can deposit a new one in the @CVar@.
33
34 data CVar a
35 = CVar (MVar a) -- prod -> cons
36 (MVar ()) -- cons -> prod
37
38 newCVar :: IO (CVar a)
39 newCVar
40 = newEmptyMVar >>= \ datum ->
41 newMVar () >>= \ ack ->
42 return (CVar datum ack)
43
44 writeCVar :: CVar a -> a -> IO ()
45
46 writeCVar (CVar datum ack) val
47 = takeMVar ack >>
48 putMVar datum val >>
49 return ()
50
51 readCVar :: CVar a -> IO a
52 readCVar (CVar datum ack)
53 = takeMVar datum >>= \ val ->
54 putMVar ack () >>
55 return val