[project @ 2002-04-24 16:31:37 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/core/LICENSE)
6 -- 
7 -- Maintainer  :  libraries@haskell.org
8 -- Stability   :  experimental
9 -- Portability :  non-portable
10 --
11 -- $Id: CVar.hs,v 1.2 2002/04/24 16:31:37 simonmar Exp $
12 --
13 -- Channel variables are one-element channels.
14 --
15 -----------------------------------------------------------------------------
16
17 module Control.Concurrent.CVar
18         ( -- abstract
19           CVar
20         , newCVar       -- :: IO (CVar a)
21         , writeCVar     -- :: CVar a -> a -> IO ()
22         , readCVar      -- :: CVar a -> IO a
23         ) where
24
25 import Prelude
26
27 import Control.Concurrent.MVar
28
29 -- @MVars@ provide the basic mechanisms for synchronising access to a
30 -- shared resource. @CVars@, or channel variables, provide an abstraction
31 -- that guarantee that the producer is not allowed to run riot, but
32 -- enforces the interleaved access to the channel variable,i.e., a
33 -- producer is forced to wait up for a consumer to remove the previous
34 -- value before it can deposit a new one in the @CVar@.
35
36 data CVar a
37  = CVar (MVar a)     -- prod -> cons
38         (MVar ())    -- cons -> prod
39
40 newCVar :: IO (CVar a)
41 newCVar 
42  = newEmptyMVar >>= \ datum ->
43    newMVar ()   >>= \ ack ->
44    return (CVar datum ack)
45
46 writeCVar :: CVar a -> a -> IO ()
47
48 writeCVar (CVar datum ack) val
49  = takeMVar ack      >> 
50    putMVar datum val >>
51    return ()
52
53 readCVar :: CVar a -> IO a
54 readCVar (CVar datum ack)
55  = takeMVar datum >>= \ val ->
56    putMVar ack () >> 
57    return val