-- 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