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


-- | Extra concurrency primitives
--   
--   The <tt>concurrent-extra</tt> package offers among other things the
--   following selection of synchronisation primitives:
--   
--   <ul>
--   <li><tt>Broadcast</tt>: Wake multiple threads by broadcasting a
--   value.</li>
--   <li><tt>Event</tt>: Wake multiple threads by signalling an event.</li>
--   <li><tt>Lock</tt>: Enforce exclusive access to a resource. Also known
--   as a binary semaphore or mutex. The package additionally provides an
--   alternative that works in the <tt>STM</tt> monad.</li>
--   <li><tt>RLock</tt>: A lock which can be acquired multiple times by the
--   same thread. Also known as a reentrant mutex.</li>
--   <li><tt>ReadWriteLock</tt>: Multiple-reader, single-writer locks. Used
--   to protect shared resources which may be concurrently read, but only
--   sequentially written.</li>
--   <li><tt>ReadWriteVar</tt>: Concurrent read, sequential write
--   variables.</li>
--   </ul>
--   
--   Please consult the API documentation of the individual modules for
--   more detailed information.
--   
--   This package was inspired by the concurrency libraries of Java and
--   Python.
@package concurrent-extra
@version 0.7.0.12


-- | This module provides an <a>STM</a> version of
--   <tt>Control.Concurrent.Lock</tt>.
--   
--   This module is intended to be imported qualified. We suggest importing
--   it like:
--   
--   <pre>
--   import           Control.Concurrent.STM.Lock         ( Lock )
--   import qualified Control.Concurrent.STM.Lock as Lock ( ... )
--   </pre>
module Control.Concurrent.STM.Lock

-- | A lock is in one of two states: "locked" or "unlocked".
data Lock

-- | Create a lock in the "unlocked" state.
new :: STM Lock

-- | Create a lock in the "locked" state.
newAcquired :: STM Lock

-- | <ul>
--   <li>When the state is "locked" <tt>acquire</tt> will <a>retry</a> the
--   transaction.</li>
--   <li>When the state is "unlocked" <tt>acquire</tt> will change the
--   state to "locked".</li>
--   </ul>
acquire :: Lock -> STM ()

-- | A non-blocking <a>acquire</a>.
--   
--   <ul>
--   <li>When the state is "unlocked" <tt>tryAcquire</tt> changes the state
--   to "locked" and returns <a>True</a>.</li>
--   <li>When the state is "locked" <tt>tryAcquire</tt> leaves the state
--   unchanged and returns <a>False</a>.</li>
--   </ul>
tryAcquire :: Lock -> STM Bool

-- | <tt>release</tt> changes the state to "unlocked" and returns
--   immediately.
--   
--   Note that it is an error to release a lock in the "unlocked" state!
release :: Lock -> STM ()

-- | A convenience function which first acquires the lock and then performs
--   the computation. When the computation terminates, whether normally or
--   by raising an exception, the lock is released.
with :: Lock -> IO a -> IO a

-- | A non-blocking <a>with</a>. <tt>tryWith</tt> is a convenience function
--   which first tries to acquire the lock. If that fails, <a>Nothing</a>
--   is returned. If it succeeds, the computation is performed. When the
--   computation terminates, whether normally or by raising an exception,
--   the lock is released and <a>Just</a> the result of the computation is
--   returned.
tryWith :: Lock -> IO a -> IO (Maybe a)

-- | <ul>
--   <li>When the state is "locked", <tt>wait</tt> will <a>retry</a> the
--   transaction</li>
--   <li>When the state is "unlocked" <tt>wait</tt> returns
--   immediately.</li>
--   </ul>
--   
--   <tt>wait</tt> does not alter the state of the lock.
--   
--   Note that <tt>wait</tt> is just a convenience function which can be
--   defined as:
--   
--   <pre>
--   wait l = <a>acquire</a> l <tt>&gt;&gt;</tt> <a>release</a> l
--   </pre>
wait :: Lock -> STM ()

-- | Determines if the lock is in the "locked" state.
--   
--   Note that this is only a snapshot of the state. By the time a program
--   reacts on its result it may already be out of date.
locked :: Lock -> STM Bool
instance GHC.Classes.Eq Control.Concurrent.STM.Lock.Lock


-- | This module provides the <a>Lock</a> synchronisation mechanism. It was
--   inspired by the Python and Java <tt>Lock</tt> objects and should
--   behave in a similar way. See:
--   
--   <a>http://docs.python.org/3.1/library/threading.html#lock-objects</a>
--   
--   and:
--   
--   
--   <a>http://java.sun.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html</a>
--   
--   All functions are <i>exception safe</i>. Throwing asynchronous
--   exceptions will not compromise the internal state of a <a>Lock</a>.
--   
--   This module is intended to be imported qualified. We suggest importing
--   it like:
--   
--   <pre>
--   import           Control.Concurrent.Lock         ( Lock )
--   import qualified Control.Concurrent.Lock as Lock ( ... )
--   </pre>
module Control.Concurrent.Lock

-- | A lock is in one of two states: "locked" or "unlocked".
data Lock

-- | Create a lock in the "unlocked" state.
new :: IO Lock

-- | Create a lock in the "locked" state.
newAcquired :: IO Lock

-- | Acquires the <a>Lock</a>. Blocks if another thread has acquired the
--   <a>Lock</a>.
--   
--   <tt>acquire</tt> behaves as follows:
--   
--   <ul>
--   <li>When the state is "unlocked" <tt>acquire</tt> changes the state to
--   "locked".</li>
--   <li>When the state is "locked" <tt>acquire</tt> <i>blocks</i> until a
--   call to <a>release</a> in another thread wakes the calling thread.
--   Upon awakening it will change the state to "locked".</li>
--   </ul>
--   
--   There are two further important properties of <tt>acquire</tt>:
--   
--   <ul>
--   <li><tt>acquire</tt> is single-wakeup. That is, if there are multiple
--   threads blocked on <tt>acquire</tt> and the lock is released, only one
--   thread will be woken up. The runtime guarantees that the woken thread
--   completes its <tt>acquire</tt> operation.</li>
--   <li>When multiple threads are blocked on <tt>acquire</tt>, they are
--   woken up in FIFO order. This is useful for providing fairness
--   properties of abstractions built using locks. (Note that this differs
--   from the Python implementation where the wake-up order is
--   undefined.)</li>
--   </ul>
acquire :: Lock -> IO ()

-- | A non-blocking <a>acquire</a>.
--   
--   <ul>
--   <li>When the state is "unlocked" <tt>tryAcquire</tt> changes the state
--   to "locked" and returns <a>True</a>.</li>
--   <li>When the state is "locked" <tt>tryAcquire</tt> leaves the state
--   unchanged and returns <a>False</a>.</li>
--   </ul>
tryAcquire :: Lock -> IO Bool

-- | <tt>release</tt> changes the state to "unlocked" and returns
--   immediately.
--   
--   Note that it is an error to release a lock in the "unlocked" state!
--   
--   If there are any threads blocked on <a>acquire</a> the thread that
--   first called <tt>acquire</tt> will be woken up.
release :: Lock -> IO ()

-- | A convenience function which first acquires the lock and then performs
--   the computation. When the computation terminates, whether normally or
--   by raising an exception, the lock is released.
--   
--   Note that: <tt>with = <a>liftA2</a> <a>bracket_</a> <a>acquire</a>
--   <a>release</a></tt>.
with :: Lock -> IO a -> IO a

-- | A non-blocking <a>with</a>. <tt>tryWith</tt> is a convenience function
--   which first tries to acquire the lock. If that fails, <a>Nothing</a>
--   is returned. If it succeeds, the computation is performed. When the
--   computation terminates, whether normally or by raising an exception,
--   the lock is released and <a>Just</a> the result of the computation is
--   returned.
tryWith :: Lock -> IO a -> IO (Maybe a)

-- | <ul>
--   <li>When the state is "locked", <tt>wait</tt> <i>blocks</i> until a
--   call to <a>release</a> in another thread changes it to
--   "unlocked".</li>
--   <li><tt>wait</tt> is multiple-wakeup, so when multiple waiters are
--   blocked on a <tt>Lock</tt>, all of them are woken up at the same
--   time.</li>
--   <li>When the state is "unlocked" <tt>wait</tt> returns
--   immediately.</li>
--   </ul>
--   
--   <tt>wait</tt> does not alter the state of the lock.
wait :: Lock -> IO ()

-- | Determines if the lock is in the "locked" state.
--   
--   Note that this is only a snapshot of the state. By the time a program
--   reacts on its result it may already be out of date.
locked :: Lock -> IO Bool
instance GHC.Classes.Eq Control.Concurrent.Lock.Lock


-- | Multiple-reader, single-writer locks. Used to protect shared resources
--   which may be concurrently read, but only sequentially written.
--   
--   All functions are <i>exception safe</i>. Throwing asynchronous
--   exceptions will not compromise the internal state of an <a>RWLock</a>.
--   This means it is perfectly safe to kill a thread that is blocking on,
--   for example, <a>acquireRead</a>.
--   
--   See also Java's version:
--   <a>http://java.sun.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html</a>
--   
--   This module is designed to be imported qualified. We suggest importing
--   it like:
--   
--   <pre>
--   import           Control.Concurrent.ReadWriteLock        ( RWLock )
--   import qualified Control.Concurrent.ReadWriteLock as RWL ( ... )
--   </pre>
module Control.Concurrent.ReadWriteLock

-- | Multiple-reader, single-writer lock. Is in one of three states:
--   
--   <ul>
--   <li>"Free": Read or write access can be acquired without
--   blocking.</li>
--   <li>"Read": One or more threads have acquired read access. Blocks
--   write access.</li>
--   <li>"Write": A single thread has acquired write access. Blocks other
--   threads from acquiring both read and write access.</li>
--   </ul>
data RWLock

-- | Create a new <a>RWLock</a> in the "free" state; either read or write
--   access can be acquired without blocking.
new :: IO RWLock

-- | Create a new <a>RWLock</a> in the "read" state; only read can be
--   acquired without blocking.
newAcquiredRead :: IO RWLock

-- | Create a new <a>RWLock</a> in the "write" state; either acquiring read
--   or write will block.
newAcquiredWrite :: IO RWLock

-- | Acquire the read lock.
--   
--   Blocks if another thread has acquired write access. If
--   <tt>acquireRead</tt> terminates without throwing an exception the
--   state of the <a>RWLock</a> will be "read".
--   
--   Implementation note: Throws an exception when more than (maxBound ::
--   Int) simultaneous threads acquire the read lock. But that is unlikely.
acquireRead :: RWLock -> IO ()

-- | Release the read lock.
--   
--   If the calling thread was the last one to relinquish read access the
--   state will revert to "free".
--   
--   It is an error to release read access to an <a>RWLock</a> which is not
--   in the "read" state.
releaseRead :: RWLock -> IO ()

-- | A convenience function wich first acquires read access and then
--   performs the computation. When the computation terminates, whether
--   normally or by raising an exception, the read lock is released.
withRead :: RWLock -> IO a -> IO a

-- | <ul>
--   <li>When the state is "write", <tt>waitRead</tt> <i>blocks</i> until a
--   call to <a>releaseWrite</a> in another thread changes the state to
--   "free".</li>
--   <li>When the state is "free" or "read" <tt>waitRead</tt> returns
--   immediately.</li>
--   </ul>
--   
--   <tt>waitRead</tt> does not alter the state of the lock.
--   
--   Note that <tt>waitRead</tt> is just a convenience function defined as:
--   
--   <pre>
--   waitRead l = <a>mask_</a> <a>$</a> <a>acquireRead</a> l <a>&gt;&gt;</a> <a>releaseRead</a> l
--   </pre>
waitRead :: RWLock -> IO ()

-- | Try to acquire the read lock; non blocking.
--   
--   Like <a>acquireRead</a>, but doesn't block. Returns <a>True</a> if the
--   resulting state is "read", <a>False</a> otherwise.
tryAcquireRead :: RWLock -> IO Bool

-- | A non-blocking <a>withRead</a>. First tries to acquire the lock. If
--   that fails, <a>Nothing</a> is returned. If it succeeds, the
--   computation is performed. When the computation terminates, whether
--   normally or by raising an exception, the lock is released and
--   <a>Just</a> the result of the computation is returned.
tryWithRead :: RWLock -> IO a -> IO (Maybe a)

-- | Acquire the write lock.
--   
--   Blocks if another thread has acquired either read or write access. If
--   <tt>acquireWrite</tt> terminates without throwing an exception the
--   state of the <a>RWLock</a> will be "write".
acquireWrite :: RWLock -> IO ()

-- | Release the write lock.
--   
--   If <tt>releaseWrite</tt> terminates without throwing an exception the
--   state will be "free".
--   
--   It is an error to release write access to an <a>RWLock</a> which is
--   not in the "write" state.
releaseWrite :: RWLock -> IO ()

-- | A convenience function wich first acquires write access and then
--   performs the computation. When the computation terminates, whether
--   normally or by raising an exception, the write lock is released.
withWrite :: RWLock -> IO a -> IO a

-- | <ul>
--   <li>When the state is "write" or "read" <tt>waitWrite</tt>
--   <i>blocks</i> until a call to <a>releaseWrite</a> or
--   <a>releaseRead</a> in another thread changes the state to "free".</li>
--   <li>When the state is "free" <tt>waitWrite</tt> returns
--   immediately.</li>
--   </ul>
--   
--   <tt>waitWrite</tt> does not alter the state of the lock.
--   
--   Note that <tt>waitWrite</tt> is just a convenience function defined
--   as:
--   
--   <pre>
--   waitWrite l = <a>mask_</a> <a>$</a> <a>acquireWrite</a> l <a>&gt;&gt;</a> <a>releaseWrite</a> l
--   </pre>
waitWrite :: RWLock -> IO ()

-- | Try to acquire the write lock; non blocking.
--   
--   Like <a>acquireWrite</a>, but doesn't block. Returns <a>True</a> if
--   the resulting state is "write", <a>False</a> otherwise.
tryAcquireWrite :: RWLock -> IO Bool

-- | A non-blocking <a>withWrite</a>. First tries to acquire the lock. If
--   that fails, <a>Nothing</a> is returned. If it succeeds, the
--   computation is performed. When the computation terminates, whether
--   normally or by raising an exception, the lock is released and
--   <a>Just</a> the result of the computation is returned.
tryWithWrite :: RWLock -> IO a -> IO (Maybe a)
instance GHC.Classes.Eq Control.Concurrent.ReadWriteLock.RWLock


-- | Concurrent read, sequential write variables. Comparable to an
--   <a>IORef</a> with more advanced synchronization mechanisms. The value
--   stored inside the <a>RWVar</a> can be read and used by multiple
--   threads at the same time. Concurrent computations inside a <a>with</a>
--   "block" observe the same value.
--   
--   Observing and changing the contents of an <a>RWVar</a> are mutually
--   exclusive. The <a>with</a> function will block if <a>modify</a> is
--   active and vice-versa. Furthermore <a>with</a> is fully sequential and
--   will also block on concurrent calls of <a>modify</a>.
--   
--   The following are guaranteed deadlocks:
--   
--   <ul>
--   <li><pre><a>modify_</a> v <a>$</a> <a>const</a> <a>$</a> <a>with</a> v
--   <a>$</a> <a>const</a> <a>undefined</a></pre></li>
--   <li><pre><a>with</a> v <a>$</a> <a>const</a> <a>$</a> <a>modify_</a> v
--   <a>$</a> <a>const</a> <a>undefined</a></pre></li>
--   <li><pre><a>modify_</a> v <a>$</a> <a>const</a> <a>$</a>
--   <a>modify_</a> v <a>$</a> <a>const</a> <a>undefined</a></pre></li>
--   </ul>
--   
--   All functions are <i>exception safe</i>. Throwing asynchronous
--   exceptions will not compromise the internal state of an <a>RWVar</a>.
--   This also means that threads blocking on <a>with</a> or <a>modify</a>
--   and friends can still be unblocked by throwing an asynchronous
--   exception.
--   
--   This module is designed to be imported qualified. We suggest importing
--   it like:
--   
--   <pre>
--   import           Control.Concurrent.ReadWriteVar        ( RWVar )
--   import qualified Control.Concurrent.ReadWriteVar as RWV ( ... )
--   </pre>
module Control.Concurrent.ReadWriteVar

-- | Concurrently readable and sequentially writable variable.
data RWVar a

-- | Create a new <a>RWVar</a>.
new :: a -> IO (RWVar a)

-- | Execute an action that operates on the contents of the <a>RWVar</a>.
--   
--   The action is guaranteed to have a consistent view of the stored
--   value. Any function that attempts to <a>modify</a> the contents will
--   block until the action is completed.
--   
--   If another thread is modifying the contents of the <a>RWVar</a> this
--   function will block until the other thread finishes its action.
with :: RWVar a -> (a -> IO b) -> IO b

-- | Like <a>with</a> but doesn't block. Returns <a>Just</a> the result if
--   read access could be acquired without blocking, <a>Nothing</a>
--   otherwise.
tryWith :: RWVar a -> (a -> IO b) -> IO (Maybe b)

-- | Modify the contents of an <a>RWVar</a>.
--   
--   This function needs exclusive write access to the <a>RWVar</a>. Only
--   one thread can modify an <a>RWVar</a> at the same time. All others
--   will block.
modify_ :: RWVar a -> (a -> IO a) -> IO ()

-- | Modify the contents of an <a>RWVar</a> and return an additional value.
--   
--   Like <a>modify_</a>, but allows a value to be returned (β) in addition
--   to the modified value of the <a>RWVar</a>.
modify :: RWVar a -> (a -> IO (a, b)) -> IO b

-- | Attempt to modify the contents of an <a>RWVar</a>.
--   
--   Like <a>modify_</a>, but doesn't block. Returns <a>True</a> if the
--   contents could be replaced, <a>False</a> otherwise.
tryModify_ :: RWVar a -> (a -> IO a) -> IO Bool

-- | Attempt to modify the contents of an <a>RWVar</a> and return an
--   additional value.
--   
--   Like <a>modify</a>, but doesn't block. Returns <a>Just</a> the
--   additional value if the contents could be replaced, <a>Nothing</a>
--   otherwise.
tryModify :: RWVar a -> (a -> IO (a, b)) -> IO (Maybe b)
instance GHC.Classes.Eq (Control.Concurrent.ReadWriteVar.RWVar a)


-- | This module provides the <a>RLock</a> synchronisation mechanism. It
--   was inspired by the Python <tt>RLock</tt> and Java
--   <tt>ReentrantLock</tt> objects and should behave in a similar way.
--   See:
--   
--   <a>http://docs.python.org/3.1/library/threading.html#rlock-objects</a>
--   
--   and:
--   
--   
--   <a>http://java.sun.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html</a>
--   
--   All functions are <i>exception safe</i>. Throwing asynchronous
--   exceptions will not compromise the internal state of an <a>RLock</a>.
--   
--   This module is intended to be imported qualified. We suggest importing
--   it like:
--   
--   <pre>
--   import           Control.Concurrent.RLock          ( RLock )
--   import qualified Control.Concurrent.RLock as RLock ( ... )
--   </pre>
module Control.Concurrent.RLock

-- | A reentrant lock is in one of two states: "locked" or "unlocked". When
--   the lock is in the "locked" state it has two additional properties:
--   
--   <ul>
--   <li>Its <i>owner</i>: the thread that acquired the lock.</li>
--   <li>Its <i>acquired count</i>: how many times its owner acquired the
--   lock.</li>
--   </ul>
data RLock

-- | Create a reentrant lock in the "unlocked" state.
new :: IO RLock

-- | Create a reentrant lock in the "locked" state (with the current thread
--   as owner and an acquired count of 1).
newAcquired :: IO RLock

-- | Acquires the <a>RLock</a>. Blocks if another thread has acquired the
--   <a>RLock</a>.
--   
--   <tt>acquire</tt> behaves as follows:
--   
--   <ul>
--   <li>When the state is "unlocked", <tt>acquire</tt> changes the state
--   to "locked" with the current thread as owner and an acquired count of
--   1.</li>
--   <li>When the state is "locked" and the current thread owns the lock
--   <tt>acquire</tt> only increments the acquired count.</li>
--   <li>When the state is "locked" and the current thread does not own the
--   lock <tt>acquire</tt> <i>blocks</i> until the owner releases the lock.
--   If the thread that called <tt>acquire</tt> is woken upon release of
--   the lock it will take ownership and change the state to "locked" with
--   an acquired count of 1.</li>
--   </ul>
--   
--   There are two further important properties of <tt>acquire</tt>:
--   
--   <ul>
--   <li><tt>acquire</tt> is single-wakeup. That is, if there are multiple
--   threads blocked on <tt>acquire</tt>, and the lock is released, only
--   one thread will be woken up. The runtime guarantees that the woken
--   thread completes its <tt>acquire</tt> operation.</li>
--   <li>When multiple threads are blocked on <tt>acquire</tt> they are
--   woken up in FIFO order. This is useful for providing fairness
--   properties of abstractions built using locks. (Note that this differs
--   from the Python implementation where the wake-up order is
--   undefined.)</li>
--   </ul>
acquire :: RLock -> IO ()

-- | A non-blocking <a>acquire</a>.
--   
--   <ul>
--   <li>When the state is "unlocked" <tt>tryAcquire</tt> changes the state
--   to "locked" (with the current thread as owner and an acquired count of
--   1) and returns <a>True</a>.</li>
--   <li>When the state is "locked" <tt>tryAcquire</tt> leaves the state
--   unchanged and returns <a>False</a>.</li>
--   </ul>
tryAcquire :: RLock -> IO Bool

-- | <tt>release</tt> decrements the acquired count. When a lock is
--   released with an acquired count of 1 its state is changed to
--   "unlocked".
--   
--   Note that it is both an error to release a lock in the "unlocked"
--   state and to release a lock that is not owned by the current thread.
--   
--   If there are any threads blocked on <a>acquire</a> the thread that
--   first called <tt>acquire</tt> will be woken up.
release :: RLock -> IO ()

-- | A convenience function which first acquires the lock and then performs
--   the computation. When the computation terminates, whether normally or
--   by raising an exception, the lock is released.
--   
--   Note that: <tt>with = <a>liftA2</a> <a>bracket_</a> <a>acquire</a>
--   <a>release</a></tt>.
with :: RLock -> IO a -> IO a

-- | A non-blocking <a>with</a>. <tt>tryWith</tt> is a convenience function
--   which first tries to acquire the lock. If that fails, <a>Nothing</a>
--   is returned. If it succeeds, the computation is performed. When the
--   computation terminates, whether normally or by raising an exception,
--   the lock is released and <a>Just</a> the result of the computation is
--   returned.
tryWith :: RLock -> IO a -> IO (Maybe a)

-- | <ul>
--   <li>When the state is "locked" <tt>wait</tt> <i>blocks</i> until a
--   call to <a>release</a> in another thread changes it to
--   "unlocked".</li>
--   <li>When the state is "unlocked" <tt>wait</tt> returns
--   immediately.</li>
--   </ul>
--   
--   <tt>wait</tt> does not alter the state of the lock.
--   
--   Note that <tt>wait</tt> is just a convenience function defined as:
--   
--   <pre>
--   wait l = <tt>block</tt> <a>$</a> <a>acquire</a> l <a>&gt;&gt;</a> <a>release</a> l
--   </pre>
wait :: RLock -> IO ()

-- | The state of an <a>RLock</a>.
--   
--   <ul>
--   <li><a>Nothing</a> indicates an "unlocked" state.</li>
--   <li><tt><a>Just</a> (tid, n)</tt> indicates a "locked" state where the
--   thread identified by <tt>tid</tt> acquired the lock <tt>n</tt>
--   times.</li>
--   </ul>
type State = Maybe (ThreadId, Integer)

-- | Determine the state of the reentrant lock.
--   
--   Note that this is only a snapshot of the state. By the time a program
--   reacts on its result it may already be out of date.
state :: RLock -> IO State
instance GHC.Classes.Eq Control.Concurrent.RLock.RLock


-- | A <a>Broadcast</a> is a mechanism for communication between threads.
--   Multiple <tt><a>listen</a>ers</tt> wait until a broadcaster
--   <tt><a>broadcast</a>s</tt> a value. The listeners block until the
--   value is received. When the broadcaster broadcasts a value all
--   listeners are woken.
--   
--   All functions are <i>exception safe</i>. Throwing asynchronous
--   exceptions will not compromise the internal state of a broadcast.
--   
--   This module is designed to be imported qualified. We suggest importing
--   it like:
--   
--   <pre>
--   import           Control.Concurrent.Broadcast              ( Broadcast )
--   import qualified Control.Concurrent.Broadcast as Broadcast ( ... )
--   </pre>
module Control.Concurrent.Broadcast

-- | A broadcast is in one of two possible states:
--   
--   <ul>
--   <li>"Silent": <tt><a>listen</a>ing</tt> to the broadcast will block
--   until a value is <tt><a>broadcast</a>ed</tt>.</li>
--   <li>"Broadcasting <tt>x</tt>": <tt><a>listen</a>ing</tt> to the
--   broadcast will return the value <tt>x</tt> without blocking.</li>
--   </ul>
data Broadcast a

-- | <tt>new</tt> creates a broadcast in the "silent" state.
new :: IO (Broadcast a)

-- | <tt>newBroadcasting x</tt> creates a broadcast in the "broadcasting
--   <tt>x</tt>" state.
newBroadcasting :: a -> IO (Broadcast a)

-- | Listen to a broadcast.
--   
--   <ul>
--   <li>If the broadcast is "broadcasting <tt>x</tt>", <tt>listen</tt>
--   will return <tt>x</tt> immediately.</li>
--   <li>If the broadcast is "silent", <tt>listen</tt> will block until
--   another thread <tt><a>broadcast</a>s</tt> a value to the
--   broadcast.</li>
--   </ul>
listen :: Broadcast a -> IO a

-- | Try to listen to a broadcast; non blocking.
--   
--   <ul>
--   <li>If the broadcast is "broadcasting <tt>x</tt>", <tt>tryListen</tt>
--   will return <a>Just</a> <tt>x</tt> immediately.</li>
--   <li>If the broadcast is "silent", <tt>tryListen</tt> returns
--   <a>Nothing</a> immediately.</li>
--   </ul>
tryListen :: Broadcast a -> IO (Maybe a)

-- | Listen to a broadcast if it is available within a given amount of
--   time.
--   
--   Like <a>listen</a>, but with a timeout. A return value of
--   <a>Nothing</a> indicates a timeout occurred.
--   
--   The timeout is specified in microseconds.
--   
--   If the broadcast is "silent" and a timeout of 0 μs is specified the
--   function returns <a>Nothing</a> without blocking.
--   
--   Negative timeouts are treated the same as a timeout of 0 μs.
listenTimeout :: Broadcast a -> Integer -> IO (Maybe a)

-- | Broadcast a value.
--   
--   <tt>broadcast b x</tt> changes the state of the broadcast <tt>b</tt>
--   to "broadcasting <tt>x</tt>".
--   
--   If the broadcast was "silent" all threads that are
--   <tt><a>listen</a>ing</tt> to the broadcast will be woken.
broadcast :: Broadcast a -> a -> IO ()

-- | Broadcast a value before becoming "silent".
--   
--   The state of the broadcast is changed to "silent" after all threads
--   that are <tt><a>listen</a>ing</tt> to the broadcast are woken and
--   resume with the signalled value.
--   
--   The semantics of signal are equivalent to the following definition:
--   
--   <pre>
--   signal b x = <tt>block</tt> $ <a>broadcast</a> b x &gt;&gt; <a>silence</a> b
--   </pre>
signal :: Broadcast a -> a -> IO ()

-- | Set a broadcast to the "silent" state.
silence :: Broadcast a -> IO ()
instance GHC.Classes.Eq (Control.Concurrent.Broadcast.Broadcast a)


-- | An Event is a simple mechanism for communication between threads: one
--   thread signals an event and other threads wait for it.
--   
--   An event has a state which is either "set" or "cleared". This state
--   can be changed with the corresponding functions <a>set</a> and
--   <a>clear</a>. The <a>wait</a> function blocks until the state is
--   "set". An important property of setting an event is that <i>all</i>
--   threads waiting for it are woken.
--   
--   It was inspired by the Python <tt>Event</tt> object. See:
--   
--   <a>http://docs.python.org/3.1/library/threading.html#event-objects</a>
--   
--   This module is designed to be imported qualified. We suggest importing
--   it like:
--   
--   <pre>
--   import           Control.Concurrent.Event          ( Event )
--   import qualified Control.Concurrent.Event as Event ( ... )
--   </pre>
module Control.Concurrent.Event

-- | An event is in one of two possible states: "set" or "cleared".
data Event

-- | Create an event in the "cleared" state.
new :: IO Event

-- | Create an event in the "set" state.
newSet :: IO Event

-- | Block until the event is <a>set</a>.
--   
--   If the state of the event is already "set" this function will return
--   immediately. Otherwise it will block until another thread calls
--   <a>set</a>.
--   
--   (You can also resume a thread that is waiting for an event by throwing
--   an asynchronous exception.)
wait :: Event -> IO ()

-- | Block until the event is <a>set</a> or until a timer expires.
--   
--   Like <a>wait</a>, but with a timeout. A return value of <a>False</a>
--   indicates a timeout occurred.
--   
--   The timeout is specified in microseconds.
--   
--   If the event is "cleared" and a timeout of 0 μs is specified the
--   function returns <a>False</a> without blocking.
--   
--   Negative timeouts are treated the same as a timeout of 0 μs.
waitTimeout :: Event -> Integer -> IO Bool

-- | Returns <a>True</a> if the state of the event is "set" and
--   <a>False</a> if the state is "cleared".
--   
--   Notice that this is only a snapshot of the state. By the time a
--   program reacts on its result it may already be out of date.
isSet :: Event -> IO Bool

-- | Changes the state of the event to "set". All threads that where
--   waiting for this event are woken. Threads that <a>wait</a> after the
--   state is changed to "set" will not block at all.
set :: Event -> IO ()

-- | Changes the state to "cleared" after all threads that where waiting
--   for this event are woken. Threads that <a>wait</a> after a
--   <tt>signal</tt> will block until the event is <a>set</a> again.
--   
--   The semantics of signal are equivalent to the following definition:
--   
--   <pre>
--   signal e = <a>mask</a> $ <a>set</a> e &gt;&gt; <a>clear</a> e
--   </pre>
signal :: Event -> IO ()

-- | Changes the state of the event to "cleared". Threads that <a>wait</a>
--   after the state is changed to "cleared" will block until the state is
--   changed to "set".
clear :: Event -> IO ()
instance GHC.Classes.Eq Control.Concurrent.Event.Event
