[project @ 2002-05-09 13:16:29 by simonmar]
[ghc-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