úÎiñhI     non-portable (concurrency) experimentalhaskell@list.mightyreason.comA N is a quantity semaphore, in which the available quantity may be signalled or " waited for in arbitrary amounts. CUsed to lock access to state of semaphore quantity. Never updated. FUsed as FIFO queue for waiter, held by head of queue. Never updated. NThis is the quantity available to be taken from the semaphore. Often updated. QIf there is waiter then this is Just the amount being waited for. Often updated. @The head of the waiter queue blocks on headWait. Never updated. Z allows positive, zero, and negative initial values. The initial value is forced here to  better localize errors. R takes a quantity of the semaphore to take and hold while performing the provided  operation. O ensures the quantity of the sempahore cannot be lost if there are exceptions.  This uses  to ensure  and  get called correctly. S takes a pure function and an operation. The pure function converts the available a quantity to a pair of the wanted quantity and a returned value. The operation takes the result  of the pure function. ? ensures the quantity of the sempahore cannot be lost if there  are exceptions. This uses  to ensure  and  get called correctly. FNote: A long running pure function will block all other access to the  while it is  evaluated. [ allow positive, zero, and negative wanted values. Waiters may block, and will be handled  fairly in FIFO order. If / returns without interruption then it left the $ with a remaining quantity that was $ greater than or equal to zero. If . is interrupted then no quantity is lost. If  c returns without interruption then it is known that each earlier waiter has definitely either been 2 interrupted or has retured without interruption. waitWith takes the H and a pure function that takes the available quantity and computes the b amount wanted and a second value. The value wanted is stricly evaluated but the second value is  returned lazily. [ allow positive, zero, and negative wanted values. Waiters may block, and will be handled  fairly in FIFO order. If / returns without interruption then it left the $ with a remaining quantity that was $ greater than or equal to zero. If 2 or the provided function are interrupted then no  quantity is lost. If B returns without interruption then it is known that each previous Y waiter has each definitely either been interrupted or has retured without interruption. FNote: A long running pure function will block all other access to the  while it is  evaluated. V allows positive, zero, and negative values, thus this is also way to remove quantity  that skips any threads in the 'wait'/'waitF'3 queue. If the new total is greater than the next b value being waited for (if present) then the first waiter is woken. If there are queued waiters a then the next one will wake after a waiter has proceeded and notice the remaining value; thus a  single L may result in several waiters obtaining values. Waking waiting threads is  asynchronous. Y may block, but it cannot be interrupted, which allows it to dependably restore value to  the . All , , 1, and the head waiter may momentarily block in a  fair FIFO manner. ?Instead of providing a fixed change to the available quantity,  applies a provided X pure function to the available quantity to compute the change and a second value. The e requested change is stricly evaluated but the second value is returned lazily. If the new total is c greater than the next value being waited for then the first waiter is woken. If there are queued b waiters then the next one will wake after a waiter has proceeded and notice the remaining value;  thus a single I may result in several waiters obtaining values. Waking waiting threads  is asynchronous. X may block, and it can be safely interrupted. If the provided function throws an error & or is interrupted then it leaves the  unchanged. All , , , and > the head waiter may momentarily block in a fair FIFO manner. FNote: A long running pure function will block all other access to the  while it is  evaluated.  skips the queue of any blocked  and  threads, but may momentarily  block on , , other 2, and the head waiter. This returns the amount of c value available to be taken. Using this value without producing unwanted race conditions is left  up to the programmer.  is an optimized form of " signalF m (x -> (0,x))".  A version of  that joins the FIFO queue of  and  can be acheived by  " waitF m (x -> (0,x))"   non-portable (concurrency) experimentalhaskell@list.mightyreason.com A  S is a semaphore in which the available quantity can be added and removed in single E units, and which can start with positive, zero, or negative value. CUsed to lock access to state of semaphore quantity. Never updated. FUsed as FIFO queue for waiter, held by head of queue. Never updated. NThis is the quantity available to be taken from the semaphore. Often updated. @The head of the waiter queue blocks on headWait. Never updated.  Z allows positive, zero, and negative initial values. The initial value is forced here to  better localize errors.  P takes a unit of value from the semaphore to hold while performing the provided  operation.  O ensures the quantity of the sempahore cannot be lost if there are exceptions.   uses  to ensure   and   get called correctly.  Z will take one unit of value from the sempahore, but will block if the quantity available  is not positive. If  / returns without interruption then it left the  $ with a remaining quantity that was $ greater than or equal to zero. If  . is interrupted then no quantity is lost. If   c returns without interruption then it is known that each earlier waiter has definitely either been 2 interrupted or has retured without interruption.  ! adds one unit to the sempahore.  Y may block, but it cannot be interrupted, which allows it to dependably restore value to  the  . All  , ;, and the head waiter may momentarily block in a fair FIFO  manner.  skips the queue of any blocked  ' threads, but may momentarily block on   , other E, and the head waiter. This returns the amount of value available to Z be taken. Using this value without producing unwanted race conditions is left up to the  programmer.  Note that Control.Concurrent.MSemNP offers a more powerful API for making decisions based on the available amount.              SafeSemaphore-0.4Control.Concurrent.MSemNControl.Concurrent.MSemMSemNnewwithwithFwaitwaitFsignalsignalF peekAvailMSemmSem queueWaitMSavail headWantsheadWaitbaseControl.Exception.Basebracketbracket_