8e16596088f885404a1b2f168ac6b1c0c7075f62
[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/core/LICENSE)
6 --
7 -- Maintainer : libraries@haskell.org
8 -- Stability : experimental
9 -- Portability : non-portable
10 --
11 -- $Id: CVar.hs,v 1.1 2001/06/28 14:15:01 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