[project @ 1996-01-08 20:28:12 by partain]
[ghc-hetmet.git] / ghc / lib / prelude / ChannelVar.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
3 %
4 \section[ChannelVar]{Channel variables}
5
6 Channel variables, are one-element channels described in the Concurrent
7 Haskell paper (available from @ftp://ftp.dcs.gla.ac.uk/pub/glasgow-fp/drafts@)
8
9 \begin{code}
10 module ChannelVar
11        (
12          {- abstract -}
13          CVar,
14          newCVar,       --:: IO (CVar a)
15          putCVar,       --:: CVar a -> a -> IO ()
16          getCVar,       --:: CVar a -> IO a
17          _MVar
18
19        ) where
20
21 import PreludeGlaST
22 import PreludePrimIO    ( newEmptyMVar, newMVar, putMVar,
23                           readMVar, takeMVar, _MVar
24                         )
25 \end{code}
26
27 @MVars@ provide the basic mechanisms for synchronising access to a shared
28 resource. @CVars@, or channel variables, provide an abstraction that guarantee
29 that the producer is not allowed to run riot, but enforces the interleaved
30 access to the channel variable,i.e., a producer is forced to wait up for
31 a consumer to remove the previous value before it can deposit a new one in the @CVar@.
32
33 \begin{code}
34
35 data CVar a
36  = CVar (_MVar a)     -- prod -> cons
37         (_MVar ())    -- cons -> prod
38
39 newCVar :: IO (CVar a)
40 putCVar :: CVar a -> a -> IO ()
41 getCVar :: CVar a -> IO a
42
43 newCVar 
44  = newEmptyMVar >>= \ datum ->
45    newMVar ()   >>= \ ack ->
46    return (CVar datum ack)
47
48 putCVar (CVar datum ack) val
49  = takeMVar ack      >> 
50    putMVar datum val >>
51    return ()
52
53 getCVar (CVar datum ack)
54  = takeMVar datum >>= \ val ->
55    putMVar ack () >> 
56    return val
57
58 \end{code}