-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Strict concurrency abstractions
--   
--   This package provides head normal form strict versions of some
--   standard Haskell concurrency abstractions (MVars,Chans), which provide
--   control over where evaluation takes place not offered by the default
--   lazy types. This may be useful for deciding when and where evaluation
--   occurs, leading to improved time or space use, depending on the
--   circumstances.
@package strict-concurrency
@version 0.2.4.1


-- | Synchronising, strict variables
--   
--   Values placed in an MVar are evaluated to head normal form before
--   being placed in the MVar, preventing a common source of space-leaks
--   involving synchronising variables.
module Control.Concurrent.MVar.Strict

-- | An <a>MVar</a> (pronounced "em-var") is a synchronising variable, used
--   for communication between concurrent threads. It can be thought of as
--   a a box, which may be empty or full.
data MVar a :: * -> *

-- | Create an <a>MVar</a> which is initially empty.
newEmptyMVar :: IO (MVar a)

-- | Create an <a>MVar</a> which contains the supplied value.
newMVar :: NFData a => a -> IO (MVar a)

-- | Return the contents of the <a>MVar</a>. If the <a>MVar</a> is
--   currently empty, <a>takeMVar</a> will wait until it is full. After a
--   <a>takeMVar</a>, the <a>MVar</a> is left empty.
--   
--   There are two further important properties of <a>takeMVar</a>:
--   
--   <ul>
--   <li><a>takeMVar</a> is single-wakeup. That is, if there are multiple
--   threads blocked in <a>takeMVar</a>, and the <a>MVar</a> becomes full,
--   only one thread will be woken up. The runtime guarantees that the
--   woken thread completes its <a>takeMVar</a> operation.</li>
--   <li>When multiple threads are blocked on an <a>MVar</a>, they are
--   woken up in FIFO order. This is useful for providing fairness
--   properties of abstractions built using <a>MVar</a>s.</li>
--   </ul>
takeMVar :: MVar a -> IO a

-- | Put a value into an <a>MVar</a>. If the <a>MVar</a> is currently full,
--   <a>putMVar</a> will wait until it becomes empty.
--   
--   There are two further important properties of <a>putMVar</a>:
--   
--   <ul>
--   <li><a>putMVar</a> is single-wakeup. That is, if there are multiple
--   threads blocked in <a>putMVar</a>, and the <a>MVar</a> becomes empty,
--   only one thread will be woken up. The runtime guarantees that the
--   woken thread completes its <a>putMVar</a> operation.</li>
--   <li>When multiple threads are blocked on an <a>MVar</a>, they are
--   woken up in FIFO order. This is useful for providing fairness
--   properties of abstractions built using <a>MVar</a>s.</li>
--   </ul>
putMVar :: NFData a => MVar a -> a -> IO ()

-- | This is a combination of <a>takeMVar</a> and <a>putMVar</a>; ie. it
--   takes the value from the <a>MVar</a>, puts it back, and also returns
--   it.
readMVar :: NFData a => MVar a -> IO a

-- | Take a value from an <a>MVar</a>, put a new value into the <a>MVar</a>
--   and return the value taken. Note that there is a race condition
--   whereby another process can put something in the <a>MVar</a> after the
--   take happens but before the put does.
swapMVar :: NFData a => MVar a -> a -> IO a

-- | A non-blocking version of <a>takeMVar</a>. The <a>tryTakeMVar</a>
--   function returns immediately, with <a>Nothing</a> if the <a>MVar</a>
--   was empty, or <tt><a>Just</a> a</tt> if the <a>MVar</a> was full with
--   contents <tt>a</tt>. After <a>tryTakeMVar</a>, the <a>MVar</a> is left
--   empty.
tryTakeMVar :: MVar a -> IO (Maybe a)

-- | A non-blocking version of <a>putMVar</a>. The <a>tryPutMVar</a>
--   function attempts to put the value <tt>a</tt> into the <a>MVar</a>,
--   returning <a>True</a> if it was successful, or <a>False</a> otherwise.
tryPutMVar :: NFData a => MVar a -> a -> IO Bool

-- | Check whether a given <a>MVar</a> is empty.
--   
--   Notice that the boolean value returned is just a snapshot of the state
--   of the MVar. By the time you get to react on its result, the MVar may
--   have been filled (or emptied) - so be extremely careful when using
--   this operation. Use <a>tryTakeMVar</a> instead if possible.
isEmptyMVar :: MVar a -> IO Bool

-- | <a>withMVar</a> is a safe wrapper for operating on the contents of an
--   <a>MVar</a>. This operation is exception-safe: it will replace the
--   original contents of the <a>MVar</a> if an exception is raised (see
--   <a>Control.Exception</a>).
withMVar :: NFData a => MVar a -> (a -> IO b) -> IO b

-- | A safe wrapper for modifying the contents of an <a>MVar</a>. Like
--   <a>withMVar</a>, <a>modifyMVar</a> will replace the original contents
--   of the <a>MVar</a> if an exception is raised during the operation.
modifyMVar_ :: NFData a => MVar a -> (a -> IO a) -> IO ()

-- | A slight variation on <a>modifyMVar_</a> that allows a value to be
--   returned (<tt>b</tt>) in addition to the modified value of the
--   <a>MVar</a>.
modifyMVar :: NFData a => MVar a -> (a -> IO (a, b)) -> IO b
addMVarFinalizer :: MVar a -> IO () -> IO ()


-- | Unbounded, element-strict channels. Elements will be evaluated to WHNF
--   on entering the channel. For some concurrency applications, this is
--   more desirable than passing an unevaluted thunk through the channel
--   (for instance, it guarantees the node willl be evaluated to WHNF in a
--   worker thead).
--   
--   Element-strict channes may potentially use more memory than lazy
--   channels
module Control.Concurrent.Chan.Strict

-- | <a>Chan</a> is an abstract type representing an unbounded FIFO
--   channel.
data Chan a

-- | Build and returns a new instance of <a>Chan</a>.
newChan :: NFData a => IO (Chan a)

-- | Write a value to a <a>Chan</a>.
writeChan :: NFData a => Chan a -> a -> IO ()

-- | Read the next value from the <a>Chan</a>.
readChan :: NFData a => Chan a -> IO a

-- | Duplicate a <a>Chan</a>: the duplicate channel begins empty, but data
--   written to either channel from then on will be available from both.
--   Hence this creates a kind of broadcast channel, where data written by
--   anyone is seen by everyone else.
dupChan :: NFData a => Chan a -> IO (Chan a)

-- | Put a data item back onto a channel, where it will be the next item
--   read.
unGetChan :: NFData a => Chan a -> a -> IO ()

-- | Returns <a>True</a> if the supplied <a>Chan</a> is empty.
isEmptyChan :: NFData a => Chan a -> IO Bool

-- | Return a lazy list representing the contents of the supplied
--   <a>Chan</a>, much like <a>hGetContents</a>.
getChanContents :: NFData a => Chan a -> IO [a]

-- | Write an entire list of items to a <a>Chan</a>.
writeList2Chan :: NFData a => Chan a -> [a] -> IO ()
instance NFData a => NFData (ChItem a)
instance NFData (MVar a)
