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


-- | Concurrency for the pipes ecosystem
--   
--   This library provides light-weight concurrency primitives for pipes,
--   with the following features:
--   
--   <ul>
--   <li><i>Simple API</i>: Use only five functions</li>
--   <li><i>Deadlock Safety</i>: Automatically avoid concurrency
--   deadlocks</li>
--   <li><i>Flexibility</i>: Build many-to-many and cyclic communication
--   topologies</li>
--   <li><i>Dynamic Graphs</i>: Add or remove readers and writers at any
--   time</li>
--   </ul>
--   
--   Import <a>Pipes.Concurrent</a> to use the library.
--   
--   Read <a>Pipes.Concurrent.Tutorial</a> for a tutorial.
@package pipes-concurrency
@version 2.0.11


-- | Asynchronous communication between pipes
module Pipes.Concurrent

-- | An exhaustible source of values
--   
--   <a>recv</a> returns <a>Nothing</a> if the source is exhausted
newtype Input a
Input :: STM (Maybe a) -> Input a
[recv] :: Input a -> STM (Maybe a)

-- | An exhaustible sink of values
--   
--   <a>send</a> returns <a>False</a> if the sink is exhausted
newtype Output a
Output :: a -> STM Bool -> Output a
[send] :: Output a -> a -> STM Bool

-- | Convert an <a>Input</a> to a <a>Producer</a>
--   
--   <a>fromInput</a> terminates when the <a>Input</a> is exhausted.
fromInput :: (MonadIO m) => Input a -> Producer' a m ()

-- | Convert an <a>Output</a> to a <a>Consumer</a>
--   
--   <a>toOutput</a> terminates when the <a>Output</a> is exhausted.
toOutput :: (MonadIO m) => Output a -> Consumer' a m ()

-- | Spawn a mailbox using the specified <a>Buffer</a> to store messages
--   
--   Using <a>send</a> on the <a>Output</a>
--   
--   <ul>
--   <li>fails and returns <a>False</a> if the mailbox is sealed, otherwise
--   it:</li>
--   <li>retries if the mailbox is full, or:</li>
--   <li>adds a message to the mailbox and returns <a>True</a>.</li>
--   </ul>
--   
--   Using <a>recv</a> on the <a>Input</a>:
--   
--   <ul>
--   <li>retrieves a message from the mailbox wrapped in <a>Just</a> if the
--   mailbox is not empty, otherwise it:</li>
--   <li>retries if the mailbox is not sealed, or:</li>
--   <li>fails and returns <a>Nothing</a>.</li>
--   </ul>
--   
--   If either the <a>Input</a> or <a>Output</a> is garbage collected the
--   mailbox will become sealed.
spawn :: Buffer a -> IO (Output a, Input a)

-- | Like <a>spawn</a>, but also returns an action to manually
--   <tt>seal</tt> the mailbox early:
--   
--   <pre>
--   (output, input, seal) &lt;- spawn' buffer
--   ...
--   </pre>
--   
--   Use the <tt>seal</tt> action to allow early cleanup of readers and
--   writers to the mailbox without waiting for the next garbage collection
--   cycle.
spawn' :: Buffer a -> IO (Output a, Input a, STM ())

-- | <a>withSpawn</a> passes its enclosed action an <a>Output</a> and
--   <a>Input</a> like you'd get from <a>spawn</a>, but automatically
--   <tt>seal</tt>s them after the action completes. This can be used when
--   you need the <tt>seal</tt>ing behavior available from 'spawn\'', but
--   want to work at a bit higher level:
--   
--   <pre>
--   withSpawn buffer $ \(output, input) -&gt; ...
--   </pre>
--   
--   <a>withSpawn</a> is exception-safe, since it uses <a>bracket</a>
--   internally.
withSpawn :: Buffer a -> ((Output a, Input a) -> IO r) -> IO r

-- | A more restrictive alternative to <a>withSpawn</a> that prevents
--   deadlocks
withBuffer :: Buffer a -> (Output a -> IO l) -> (Input a -> IO r) -> IO (l, r)

-- | <a>Buffer</a> specifies how to buffer messages stored within the
--   mailbox
data Buffer a

-- | <i>Deprecated: Use <a>unbounded</a> instead</i>
Unbounded :: Buffer a

-- | <i>Deprecated: Use <a>bounded</a> instead</i>
Bounded :: Int -> Buffer a

-- | <i>Deprecated: Use <tt><a>bounded</a> 1</tt> instead</i>
Single :: Buffer a

-- | <i>Deprecated: Use <a>latest</a> instead</i>
Latest :: a -> Buffer a

-- | <i>Deprecated: Use <a>newest</a> instead</i>
Newest :: Int -> Buffer a

-- | <i>Deprecated: Use <tt><a>newest</a> 1</tt> instead</i>
New :: Buffer a

-- | Store an unbounded number of messages in a FIFO queue
unbounded :: Buffer a

-- | Store a bounded number of messages, specified by the <a>Int</a>
--   argument
bounded :: Int -> Buffer a

-- | Only store the <a>Latest</a> message, beginning with an initial value
--   
--   <a>Latest</a> is never empty nor full.
latest :: a -> Buffer a

-- | Like <tt>Bounded</tt>, but <a>send</a> never fails (the buffer is
--   never full). Instead, old elements are discarded to make room for new
--   elements
newest :: Int -> Buffer a

-- | Creates a new thread to run the <a>IO</a> computation passed as the
--   first argument, and returns the <a>ThreadId</a> of the newly created
--   thread.
--   
--   The new thread will be a lightweight, <i>unbound</i> thread. Foreign
--   calls made by this thread are not guaranteed to be made by any
--   particular OS thread; if you need foreign calls to be made by a
--   particular OS thread, then use <a>forkOS</a> instead.
--   
--   The new thread inherits the <i>masked</i> state of the parent (see
--   <a>mask</a>).
--   
--   The newly created thread has an exception handler that discards the
--   exceptions <a>BlockedIndefinitelyOnMVar</a>,
--   <a>BlockedIndefinitelyOnSTM</a>, and <a>ThreadKilled</a>, and passes
--   all other exceptions to the uncaught exception handler.
forkIO :: IO () -> IO ThreadId

-- | Return the current value stored in a <a>TVar</a>.
readTVar :: () => TVar a -> STM a

-- | <tt>IO</tt> version of <a>newTVar</a>. This is useful for creating
--   top-level <a>TVar</a>s using <a>unsafePerformIO</a>, because using
--   <a>atomically</a> inside <a>unsafePerformIO</a> isn't possible.
newTVarIO :: () => a -> IO TVar a

-- | Perform a series of STM actions atomically.
--   
--   Using <a>atomically</a> inside an <a>unsafePerformIO</a> or
--   <a>unsafeInterleaveIO</a> subverts some of guarantees that STM
--   provides. It makes it possible to run a transaction inside of another
--   transaction, depending on when the thunk is evaluated. If a nested
--   transaction is attempted, an exception is thrown by the runtime. It is
--   possible to safely use <a>atomically</a> inside <a>unsafePerformIO</a>
--   or <a>unsafeInterleaveIO</a>, but the typechecker does not rule out
--   programs that may attempt nested transactions, meaning that the
--   programmer must take special care to prevent these.
--   
--   However, there are functions for creating transactional variables that
--   can always be safely called in <a>unsafePerformIO</a>. See:
--   <a>newTVarIO</a>, <tt>newTChanIO</tt>, <tt>newBroadcastTChanIO</tt>,
--   <tt>newTQueueIO</tt>, <tt>newTBQueueIO</tt>, and <tt>newTMVarIO</tt>.
--   
--   Using <a>unsafePerformIO</a> inside of <a>atomically</a> is also
--   dangerous but for different reasons. See <a>unsafeIOToSTM</a> for more
--   on this.
atomically :: () => STM a -> IO a

-- | A monad supporting atomic memory transactions.
data STM a

-- | Make a <a>Weak</a> pointer to a <a>TVar</a>, using the second argument
--   as a finalizer to run when <a>TVar</a> is garbage-collected
mkWeakTVar :: () => TVar a -> IO () -> IO Weak TVar a

-- | Triggers an immediate major garbage collection.
performGC :: IO ()
instance GHC.Base.Semigroup (Pipes.Concurrent.Output a)
instance GHC.Base.Monoid (Pipes.Concurrent.Output a)
instance Data.Functor.Contravariant.Contravariant Pipes.Concurrent.Output
instance Data.Functor.Contravariant.Divisible.Divisible Pipes.Concurrent.Output
instance Data.Functor.Contravariant.Divisible.Decidable Pipes.Concurrent.Output
instance GHC.Base.Functor Pipes.Concurrent.Input
instance GHC.Base.Applicative Pipes.Concurrent.Input
instance GHC.Base.Monad Pipes.Concurrent.Input
instance GHC.Base.Alternative Pipes.Concurrent.Input
instance GHC.Base.MonadPlus Pipes.Concurrent.Input
instance GHC.Base.Semigroup (Pipes.Concurrent.Input a)
instance GHC.Base.Monoid (Pipes.Concurrent.Input a)


-- | This module provides a tutorial for the <tt>pipes-concurrency</tt>
--   library.
--   
--   This tutorial assumes that you have read the <tt>pipes</tt> tutorial
--   in <tt>Pipes.Tutorial</tt>.
--   
--   I've condensed all the code examples into self-contained code listings
--   in the Appendix section that you can use to follow along.
module Pipes.Concurrent.Tutorial
