SafeSemaphore-0.7.0: Much safer replacement for QSemN, QSem, and SampleVar

Portabilitynon-portable (concurrency)
Stabilityexperimental
Maintainerhaskell@list.mightyreason.com

Control.Concurrent.MSem

Description

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.

The functions below are generic in (Integral i) with specialization to Int and Integer.

Overflow warning: These operations do not check for overflow errors. If the Integral type is too small to accept the new total then the behavior of these operations is undefined. Using (MSem Integer) prevents the possibility of an overflow error.

Synopsis

Documentation

data MSem i Source

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.

Instances

new :: Integral i => i -> IO (MSem i)Source

new allows positive, zero, and negative initial values. The initial value is forced here to better localize errors.

The only way to acheive a negative value with MSem is to start negative with new. Once the quantity

with :: Integral i => MSem i -> IO a -> IO aSource

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.

wait :: Integral i => MSem i -> IO ()Source

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.

signal :: Integral i => MSem i -> IO ()Source

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.

peekAvail :: Integral i => MSem i -> IO iSource

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.