-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Much safer replacement for QSemN and QSem
--
-- This provides a much safer semaphore than the QSem in base.
-- Performance has not been compared.
@package SafeSemaphore
@version 0.4
-- | Quantity semaphores in which each thread may wait for an arbitrary
-- amount. This modules is intended to improve on
-- Control.Concurrent.QSemN.
--
-- This semaphore gracefully handles threads which die while blocked
-- waiting for quantity. The fairness guarantee is that blocked threads
-- are FIFO. An early thread waiting for a large quantity will prevent a
-- later thread waiting for a small quantity from jumping the queue.
--
-- If with is used to guard a critical section then no quantity of
-- the semaphore will be lost if the activity throws an exception.
module Control.Concurrent.MSemN
-- | A MSemN is a quantity semaphore, in which the available
-- quantity may be signalled or waited for in arbitrary amounts.
data MSemN
-- | new allows positive, zero, and negative initial values. The
-- initial value is forced here to better localize errors.
new :: Integer -> IO MSemN
-- | with takes a quantity of the semaphore to take and hold while
-- performing the provided operation. with ensures the quantity of
-- the sempahore cannot be lost if there are exceptions. This uses
-- bracket to ensure wait and signal get called
-- correctly.
with :: MSemN -> Integer -> IO a -> IO a
-- | wait allow positive, zero, and negative wanted values. Waiters
-- may block, and will be handled fairly in FIFO order.
--
-- If wait returns without interruption then it left the
-- MSemN with a remaining quantity that was greater than or equal
-- to zero. If wait is interrupted then no quantity is lost. If
-- wait returns without interruption then it is known that each
-- earlier waiter has definitely either been interrupted or has retured
-- without interruption.
wait :: MSemN -> Integer -> IO ()
-- | signal allows positive, zero, and negative values, thus this is
-- also way to remove quantity that skips any threads in the
-- 'wait'/'waitF' queue. If the new total is greater than the next value
-- being waited for (if present) then the first waiter is woken. If there
-- are queued waiters then the next one will wake after a waiter has
-- proceeded and notice the remaining value; thus a single signal
-- may result in several waiters obtaining values. Waking waiting threads
-- is asynchronous.
--
-- signal may block, but it cannot be interrupted, which allows it
-- to dependably restore value to the MSemN. All signal,
-- signalF, peekAvail, and the head waiter may momentarily
-- block in a fair FIFO manner.
signal :: MSemN -> Integer -> IO ()
-- | withF takes a pure function and an operation. The pure function
-- converts the available quantity to a pair of the wanted quantity and a
-- returned value. The operation takes the result of the pure function.
-- withF ensures the quantity of the sempahore cannot be lost if
-- there are exceptions. This uses bracket to ensure waitF
-- and signal get called correctly.
--
-- Note: A long running pure function will block all other access to the
-- MSemN while it is evaluated.
withF :: MSemN -> (Integer -> (Integer, b)) -> ((Integer, b) -> IO a) -> IO a
-- | waitWith takes the MSemN and a pure function that
-- takes the available quantity and computes the amount wanted and a
-- second value. The value wanted is stricly evaluated but the second
-- value is returned lazily.
--
-- waitF allow positive, zero, and negative wanted values. Waiters
-- may block, and will be handled fairly in FIFO order.
--
-- If waitF returns without interruption then it left the
-- MSemN with a remaining quantity that was greater than or equal
-- to zero. If waitF or the provided function are interrupted then
-- no quantity is lost. If waitF returns without interruption then
-- it is known that each previous waiter has each definitely either been
-- interrupted or has retured without interruption.
--
-- Note: A long running pure function will block all other access to the
-- MSemN while it is evaluated.
waitF :: MSemN -> (Integer -> (Integer, b)) -> IO (Integer, b)
-- | Instead of providing a fixed change to the available quantity,
-- signalF applies a provided pure function to the available
-- quantity to compute the change and a second value. The requested
-- change is stricly evaluated but the second value is returned lazily.
-- If the new total is greater than the next value being waited for then
-- the first waiter is woken. If there are queued waiters then the next
-- one will wake after a waiter has proceeded and notice the remaining
-- value; thus a single signalF may result in several waiters
-- obtaining values. Waking waiting threads is asynchronous.
--
-- signalF may block, and it can be safely interrupted. If the
-- provided function throws an error or is interrupted then it leaves the
-- MSemN unchanged. All signal, signalF,
-- peekAvail, and the head waiter may momentarily block in a fair
-- FIFO manner.
--
-- Note: A long running pure function will block all other access to the
-- MSemN while it is evaluated.
signalF :: MSemN -> (Integer -> (Integer, b)) -> IO (Integer, b)
-- | peekAvail skips the queue of any blocked wait and
-- waitF threads, but may momentarily block on signal,
-- signalF, other peekAvail, and the head waiter. This
-- returns the amount of value available to be taken. Using this value
-- without producing unwanted race conditions is left up to the
-- programmer.
--
-- peekAvail is an optimized form of "signalF m (x -> (0,x))".
--
-- A version of peekAvail that joins the FIFO queue of wait
-- and waitF can be acheived by "waitF m (x -> (0,x))"
peekAvail :: MSemN -> IO Integer
instance Typeable MS
instance Typeable MSemN
instance Eq MS
instance Eq MSemN
-- | A semaphore in which operations may wait for or signal
-- single units of value. This modules is intended to improve on
-- Control.Concurrent.QSem.
--
-- This semaphore gracefully handles threads which die while blocked
-- waiting. The fairness guarantee is that blocked threads are FIFO.
--
-- If with is used to guard a critical section then no quantity of
-- the semaphore will be lost if the activity throws an exception.
-- new can initialize the semaphore to negative, zero, or positive
-- quantity. wait always leaves the MSem with non-negative
-- quantity.
module Control.Concurrent.MSem
-- | A MSem is a semaphore in which the available quantity can be
-- added and removed in single units, and which can start with positive,
-- zero, or negative value.
data MSem
-- | new allows positive, zero, and negative initial values. The
-- initial value is forced here to better localize errors.
new :: Integer -> IO MSem
-- | with takes a unit of value from the semaphore to hold while
-- performing the provided operation. with ensures the quantity of
-- the sempahore cannot be lost if there are exceptions.
--
-- with uses bracket_ to ensure wait and
-- signal get called correctly.
with :: MSem -> IO a -> IO a
-- | wait will take one unit of value from the sempahore, but will
-- block if the quantity available is not positive.
--
-- If wait returns without interruption then it left the
-- MSem with a remaining quantity that was greater than or equal
-- to zero. If wait is interrupted then no quantity is lost. If
-- wait returns without interruption then it is known that each
-- earlier waiter has definitely either been interrupted or has retured
-- without interruption.
wait :: MSem -> IO ()
-- | signal adds one unit to the sempahore.
--
-- signal may block, but it cannot be interrupted, which allows it
-- to dependably restore value to the MSem. All signal,
-- peekAvail, and the head waiter may momentarily block in a fair
-- FIFO manner.
signal :: MSem -> IO ()
-- | peekAvail skips the queue of any blocked wait threads,
-- but may momentarily block on signal, other peekAvail,
-- and the head waiter. This returns the amount of value available to be
-- taken. Using this value without producing unwanted race conditions is
-- left up to the programmer.
--
-- Note that Control.Concurrent.MSemN offers a more powerful API
-- for making decisions based on the available amount.
peekAvail :: MSem -> IO Integer
instance Typeable MS
instance Typeable MSem
instance Eq MS
instance Eq MSem