úÎ6 0P      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOSafePStrict function composition.PQRSTUVWPQRSTPQRST*(c) 2010-2011 Bas van Dijk & Roel van DijkBSD3 (see the file LICENSE)XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com> Trustworthy0 7A lock is in one of two states: "locked" or "unlocked".&Create a lock in the "unlocked" state.$Create a lock in the "locked" state.When the state is "locked" acquire will X the transaction.When the state is "unlocked" acquire# will change the state to "locked".A non-blocking .When the state is "unlocked"  tryAcquire+ changes the state to "locked" and returns Y.When the state is "locked"  tryAcquire( leaves the state unchanged and returns Z.release9 changes the state to "unlocked" and returns immediately.CNote that it is an error to release a lock in the "unlocked" state!»A convenience function which first acquires the lock and then performs the computation. When the computation terminates, whether normally or by raising an exception, the lock is released.A non-blocking . tryWithQ is a convenience function which first tries to acquire the lock. If that fails, [£ is returned. If it succeeds, the computation is performed. When the computation terminates, whether normally or by raising an exception, the lock is released and \+ the result of the computation is returned.When the state is "locked", wait will X the transactionWhen the state is "unlocked" wait returns immediately.wait& does not alter the state of the lock. Note that wait8 is just a convenience function which can be defined as:  wait l =  l ]  l 0Determines if the lock is in the "locked" state.yNote that this is only a snapshot of the state. By the time a program reacts on its result it may already be out of date. ^_   ^_ *(c) 2010-2011 Bas van Dijk & Roel van DijkBSD3 (see the file LICENSE)XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com>Safe0 7A lock is in one of two states: "locked" or "unlocked". &Create a lock in the "unlocked" state. $Create a lock in the "locked" state. Acquires the  ,. Blocks if another thread has acquired the  .acquire behaves as follows:When the state is "unlocked" acquire changes the state to "locked".When the state is "locked" acquire blocks until a call to a in another thread wakes the calling thread. Upon awakening it will change the state to "locked"..There are two further important properties of acquire:acquireE is single-wakeup. That is, if there are multiple threads blocked on acquirex and the lock is released, only one thread will be woken up. The runtime guarantees that the woken thread completes its acquire operation.%When multiple threads are blocked on acquireÔ, they are woken up in FIFO order. This is useful for providing fairness properties of abstractions built using locks. (Note that this differs from the Python implementation where the wake-up order is undefined.)A non-blocking .When the state is "unlocked"  tryAcquire+ changes the state to "locked" and returns Y.When the state is "locked"  tryAcquire( leaves the state unchanged and returns Z.release9 changes the state to "unlocked" and returns immediately.CNote that it is an error to release a lock in the "unlocked" state!$If there are any threads blocked on  the thread that first called acquire will be woken up.»A convenience function which first acquires the lock and then performs the computation. When the computation terminates, whether normally or by raising an exception, the lock is released. Note that: with = ` a  .A non-blocking . tryWithQ is a convenience function which first tries to acquire the lock. If that fails, [£ is returned. If it succeeds, the computation is performed. When the computation terminates, whether normally or by raising an exception, the lock is released and \+ the result of the computation is returned.When the state is "locked", wait blocks until a call to , in another thread changes it to "unlocked".When the state is "unlocked" wait returns immediately.wait& does not alter the state of the lock. Note that wait5 is just a convenience function we can be defined as:  wait l = block b  l ]  l0Determines if the lock is in the "locked" state.yNote that this is only a snapshot of the state. By the time a program reacts on its result it may already be out of date. cd    cd *(c) 2010-2011 Bas van Dijk & Roel van DijkBSD3 (see the file LICENSE)XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com>Safe0 The state of an .[ indicates an "unlocked" state.\ (tid, n); indicates a "locked" state where the thread identified by tid acquired the lock n times.ŠA reentrant lock is in one of two states: "locked" or "unlocked". When the lock is in the "locked" state it has two additional properties:Its owner$: the thread that acquired the lock.Its acquired count-: how many times its owner acquired the lock.0Create a reentrant lock in the "unlocked" state.lCreate a reentrant lock in the "locked" state (with the current thread as owner and an acquired count of 1). Acquires the ,. Blocks if another thread has acquired the .acquire behaves as follows:When the state is "unlocked", acquire[ changes the state to "locked" with the current thread as owner and an acquired count of 1.@When the state is "locked" and the current thread owns the lock acquire$ only increments the acquired count.HWhen the state is "locked" and the current thread does not own the lock acquire blocks> until the owner releases the lock. If the thread that called acquirew is woken upon release of the lock it will take ownership and change the state to "locked" with an acquired count of 1..There are two further important properties of acquire:acquireE is single-wakeup. That is, if there are multiple threads blocked on acquirey, and the lock is released, only one thread will be woken up. The runtime guarantees that the woken thread completes its acquire operation.%When multiple threads are blocked on acquireÓ they are woken up in FIFO order. This is useful for providing fairness properties of abstractions built using locks. (Note that this differs from the Python implementation where the wake-up order is undefined.)A non-blocking .When the state is "unlocked"  tryAcquirei changes the state to "locked" (with the current thread as owner and an acquired count of 1) and returns Y.When the state is "locked"  tryAcquire( leaves the state unchanged and returns Z.releasew decrements the acquired count. When a lock is released with an acquired count of 1 its state is changed to "unlocked".†Note that it is both an error to release a lock in the "unlocked" state and to release a lock that is not owned by the current thread.$If there are any threads blocked on  the thread that first called acquire will be woken up.»A convenience function which first acquires the lock and then performs the computation. When the computation terminates, whether normally or by raising an exception, the lock is released. Note that: with = ` a  .A non-blocking . tryWithQ is a convenience function which first tries to acquire the lock. If that fails, [£ is returned. If it succeeds, the computation is performed. When the computation terminates, whether normally or by raising an exception, the lock is released and \+ the result of the computation is returned.When the state is "locked" wait blocks until a call to , in another thread changes it to "unlocked".When the state is "unlocked" wait returns immediately.wait& does not alter the state of the lock. Note that wait+ is just a convenience function defined as:  wait l = block b  l ]  l *Determine the state of the reentrant lock.yNote that this is only a snapshot of the state. By the time a program reacts on its result it may already be out of date. ef   ef *(c) 2010-2011 Bas van Dijk & Roel van DijkBSD3 (see the file LICENSE)XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com>Safe#0gInternal state of the "."?Multiple-reader, single-writer lock. Is in one of three states:>"Free": Read or write access can be acquired without blocking.K"Read": One or more threads have acquired read access. Blocks write access.s"Write": A single thread has acquired write access. Blocks other threads from acquiring both read and write access.# Create a new "T in the "free" state; either read or write access can be acquired without blocking.$ Create a new "B in the "read" state; only read can be acquired without blocking.% Create a new "B in the "write" state; either acquiring read or write will block.&Acquire the read lock.7Blocks if another thread has acquired write access. If  acquireRead; terminates without throwing an exception the state of the " will be "read".‹Implementation note: Throws an exception when more than (maxBound :: Int) simultaneous threads acquire the read lock. But that is unlikely.'+Try to acquire the read lock; non blocking.Like &, but doesn't block. Returns Y# if the resulting state is "read", Z otherwise.(Release the read lock.aIf the calling thread was the last one to relinquish read access the state will revert to "free".,It is an error to release read access to an "" which is not in the "read" state.)ÂA convenience function wich first acquires read access and then performs the computation. When the computation terminates, whether normally or by raising an exception, the read lock is released.*A non-blocking )2. First tries to acquire the lock. If that fails, [£ is returned. If it succeeds, the computation is performed. When the computation terminates, whether normally or by raising an exception, the lock is released and \+ the result of the computation is returned.+When the state is "write", waitRead blocks until a call to ./ in another thread changes the state to "free".#When the state is "free" or "read" waitRead returns immediately.waitRead& does not alter the state of the lock. Note that waitRead+ is just a convenience function defined as:  waitRead l = V b & l ] ( l,Acquire the write lock.FBlocks if another thread has acquired either read or write access. If  acquireWrite; terminates without throwing an exception the state of the " will be "write".-,Try to acquire the write lock; non blocking.Like ,, but doesn't block. Returns Y$ if the resulting state is "write", Z otherwise..Release the write lock.If  releaseWriteC terminates without throwing an exception the state will be "free".-It is an error to release write access to an "# which is not in the "write" state./ÄA convenience function wich first acquires write access and then performs the computation. When the computation terminates, whether normally or by raising an exception, the write lock is released.0A non-blocking /2. First tries to acquire the lock. If that fails, [£ is returned. If it succeeds, the computation is performed. When the computation terminates, whether normally or by raising an exception, the lock is released and \+ the result of the computation is returned.1$When the state is "write" or "read"  waitWrite blocks until a call to . or (/ in another thread changes the state to "free".When the state is "free"  waitWrite returns immediately. waitWrite& does not alter the state of the lock. Note that  waitWrite+ is just a convenience function defined as: waitWrite l = V b , l ] . lghij"klmn#$%&'()*+,-./01o2"#$%&'()*+,-./01"#$%&()+'*,./1-0ghij"klmn#$%&'()*+,-./01o2&2010 2011 Bas van Dijk & Roel van DijkBSD3 (see the file LICENSE)XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com>Safe0L39Concurrently readable and sequentially writable variable.4 Create a new 3.57Execute an action that operates on the contents of the 3.fThe action is guaranteed to have a consistent view of the stored value. Any function that attempts to 87 the contents will block until the action is completed.3If another thread is modifying the contents of the 3E this function will block until the other thread finishes its action.6Like 5 but doesn't block. Returns \? the result if read access could be acquired without blocking, [ otherwise.7Modify the contents of an 3.2This function needs exclusive write access to the 3 . Only one thread can modify an 3) at the same time. All others will block.8Modify the contents of an 3 and return an additional value.Like 7Q, but allows a value to be returned (²) in addition to the modified value of the 3.9%Attempt to modify the contents of an 3.Like 7, but doesn't block. Returns Y$ if the contents could be replaced, Z otherwise.:%Attempt to modify the contents of an 3 and return an additional value.Like 8, but doesn't block. Returns \9 the additional value if the contents could be replaced, [ otherwise. 3p456789:;3456789:3456789: 3p456789:;*(c) 2010-2011 Bas van Dijk & Roel van DijkBSD3 (see the file LICENSE)XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com>Safe0 <-A broadcast is in one of two possible states: "Silent": ?ing. to the broadcast will block until a value is Bed."Broadcasting x": ?ing( to the broadcast will return the value x without blocking.=new+ creates a broadcast in the "silent" state.>newBroadcasting x* creates a broadcast in the "broadcasting x" state.?Listen to a broadcast."If the broadcast is "broadcasting x", listen will return x immediately.If the broadcast is "silent", listen! will block until another thread Bs a value to the broadcast.@+Try to listen to a broadcast; non blocking."If the broadcast is "broadcasting x",  tryListen will return \ x immediately.If the broadcast is "silent",  tryListen returns [ immediately.AGListen to a broadcast if it is available within a given amount of time.Like ?(, but with a timeout. A return value of [ indicates a timeout occurred.)The timeout is specified in microseconds.UIf the broadcast is "silent" and a timeout of 0 ¼s is specified the function returns [ without blocking.<Negative timeouts are treated the same as a timeout of 0 ¼s.BBroadcast a value. broadcast b x$ changes the state of the broadcast b to "broadcasting x".3If the broadcast was "silent" all threads that are ?ing to the broadcast will be woken.C+Broadcast a value before becoming "silent".MThe state of the broadcast is changed to "silent" after all threads that are ?ing@ to the broadcast are woken and resume with the signalled value.CThe semantics of signal are equivalent to the following definition:  signal b x = block $ B b x >> D b q?Internally used function that performs the actual broadcast in B and C' then changes to the given final state.D&Set a broadcast to the "silent" state. <rs=>?@ABCqD <=>?@ABCD <=>?@ABCD <rs=>?@ABCqD*(c) 2010-2011 Bas van Dijk & Roel van DijkBSD3 (see the file LICENSE)XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com>Safe0 F>An event is in one of two possible states: "set" or "cleared".G'Create an event in the "cleared" state.H#Create an event in the "set" state.IBlock until the event is L.…If the state of the event is already "set" this function will return immediately. Otherwise it will block until another thread calls L.b(You can also resume a thread that is waiting for an event by throwing an asynchronous exception.)JBlock until the event is L or until a timer expires.Like I(, but with a timeout. A return value of Z indicates a timeout occurred.)The timeout is specified in microseconds.RIf the event is "cleared" and a timeout of 0 ¼s is specified the function returns Z without blocking.<Negative timeouts are treated the same as a timeout of 0 ¼s.KReturns Y( if the state of the event is "set" and Z if the state is "cleared".{Notice that this is only a snapshot of the state. By the time a program reacts on its result it may already be out of date.LoChanges the state of the event to "set". All threads that where waiting for this event are woken. Threads that I; after the state is changed to "set" will not block at all.MkChanges the state to "cleared" after all threads that where waiting for this event are woken. Threads that I after a signal will block until the event is L again.CThe semantics of signal are equivalent to the following definition:  signal e = U $ L e >> N e N:Changes the state of the event to "cleared". Threads that IX after the state is changed to "cleared" will block until the state is changed to "set". FtuGHIJKLMN FGHIJKLMN FGHIJKLMN FtuGHIJKLMNv                !"#$%&'( )*+,-. /01234567 89:;4<=>?@ABCDECDFCGHCIJKLMKLNCOPCOQCOR SCOTCUVCOW SSXYZ[\](^._7`a0concurrent-extra-0.7.0.10-G3ufVyesTVkE2oT9UI4NqLControl.Concurrent.STM.LockControl.Concurrent.LockControl.Concurrent.RLock Control.Concurrent.ReadWriteLockControl.Concurrent.ReadWriteVarControl.Concurrent.BroadcastControl.Concurrent.EventUtilsLocknew newAcquiredacquire tryAcquirereleasewithtryWithwaitlocked$fEqLockStateRLockstate $fEqRLockRWLocknewAcquiredReadnewAcquiredWrite acquireReadtryAcquireRead releaseReadwithRead tryWithReadwaitRead acquireWritetryAcquireWrite releaseWrite withWrite tryWithWrite waitWrite $fEqRWLockRWVarmodify_modify tryModify_ tryModify $fEqRWVar BroadcastnewBroadcastinglisten tryListen listenTimeout broadcastsignalsilence $fEqBroadcastEventnewSet waitTimeoutisSetsetclear $fEqEvent.!ifMpurelyModifyMVar modifyIORefM modifyIORefM_baseGHC.IOmaskmask_ Data.Functorvoid GHC.Conc.Syncretryghc-prim GHC.TypesTrueFalseGHC.BaseNothingJust>>unliftA2Control.Exception.Basebracket_$FreeReadWritereadLock writeLock moduleName broadcastThen unBroadcast evBroadcast