6      !"#$%&'()*+,-./012345XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com>  A lock is in one of two states, "locked" or "unlocked". 67Create an unlocked lock. Create a locked lock. When the state is unlocked, acquire! changes the state to locked and /returns immediately. When the state is locked, acquire blocks until a call to 4 in another thread changes it to unlocked, then the acquire call !resets it to locked and returns. .There are two further important properties of acquire:  acquireE is single-wakeup. That is, if there are multiple threads blocked on acquireB, and the lock is released, only one thread will be woken up. The 7runtime guarantees that the woken thread completes its acquire operation. & When multiple threads are blocked on acquire, they are woken up in FIFO Norder. This is useful for providing fairness properties of abstractions built Nusing 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 1the state to locked and returns immediately with True. When the state is locked,  tryAcquire9 leaves the state unchanged and returns immediately with False. release8 changes the state to unlocked and returns immediately. 6Note that it is an error to release an unlocked lock! $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 Cperforms the computation. When the computation terminates, whether ;normally or by raising an exception, the lock is released.  Note that: with = 8 9  . A non-blocking . tryWith- is a convenience function which first tries $to acquire the lock. If that fails, :" is returned. If it succeeds, the Ocomputation is performed. When the computation terminates, whether normally or 2by raising an exception, the lock is released and ; the result of the computation is returned. /Determines if the lock is in the locked state. HNotice that this is only a snapshot of the state. By the time a program 5 reacts on its result it may already be out of date.   XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com> <=    XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com> The internal state of an  . Only interesting when you use  the  function. +An event is in one of two possible states:  or . >?&Create an event. The initial state is . Block until the event is . %If the state of the event is already  this function will return A immediately. Otherwise it will block until another thread calls . GYou can also stop a thread that is waiting for an event by throwing an  asynchronous exception. Block until the event is  or until a timer expires. Like ' but with a timeout. A return value of @ indicates a timeout  occurred. 9The timeout is specified in microseconds. A timeout of 0  s will cause  the function to return @- without blocking in case the event state is  ;. Negative timeouts are treated the same as a timeout of 0  :s. The maximum timeout is constrained by the range of the A B type. The Haskell standard guarantees an upper bound of at least 2^29-1 & giving a maximum timeout of at least  (2^29-1) / 10^6 = ~536 seconds. "Changes the state of the event to %. All threads that where waiting for $ this event are woken. Threads that  after the state is changed to   will not block at all. "Changes the state of the event to . Threads that  after the  state is changed to * will block until the state is changed to . +Determines the current state of the event. HNotice that this is only a snapshot of the state. By the time a program L reacts on its result it may already be out of date. This can be avoided by 4 synchronizing access to the event between threads.   XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com>+An event is in one of two possible states:  or . B&Create an event. The initial state is . Retry until the event is . %If the state of the event is already  this function will return A immediately. Otherwise it will retry until another thread calls . GYou can also stop a thread that is waiting for an event by throwing an  asynchronous exception. "Changes the state of the event to %. All threads that where waiting for $ this event are woken. Threads that  after the state is changed to   will not retry. "Changes the state of the event to . Threads that  after the  state is changed to * will retry until the state is changed to . ! The current state of the event.  !  ! !XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com>CInternal state of the ". DEF"@Multiple-reader, single-writer lock. Is in one of three states:  "Free"9: Read or write access can be acquired without blocking.  "Read"F: One or more threads have acquired read access. Blocks write access.  "Write"B: A single thread has acquired write access. Blocks other threads +from acquiring both read and write access. GHIJ# Create a new ". The initial state is "free"; either read or write )access can be acquired without blocking. $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". JImplementation note: Throws an exception when more than (maxBound :: Int) Bsimultaneous threads acquire the read lock. But that is unlikely. %,Try to acquire the read lock; non blocking. Like $ , but doesn't block. Returns K if the resulting state is "read", @ otherwise. &Release the read lock. PIf 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. 'MA convenience function wich first acquires read access and then performs the Pcomputation. 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, :E is returned. If it succeeds, the computation is performed. When the Qcomputation terminates, whether normally or by raising an exception, the lock is  released and ;, the result of the computation is returned. )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 K if the resulting state is "write", @ otherwise. +Release the write lock. If  releaseWrite< 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. ,JA convenience function wich first acquires write access and then performs Qthe computation. When the computation terminates, whether normally or by raising *an exception, the write lock is released. -A non-blocking ,2. First tries to acquire the lock. If that fails, :E is returned. If it succeeds, the computation is performed. When the Qcomputation terminates, whether normally or by raising an exception, the lock is  released and ;, the result of the computation is returned. LM "#$%&'()*+,- "#$&'%()+,*- "#$%&'()*+,-XBas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com> .:Concurrently readable and sequentially writable variable. N/ Create a new .. 07Execute an action that operates on the contents of the .. LThe action is guaranteed to have a consistent view of the stored value. Any function that attempts to 3- the contents will block until the action is  completed. 3If another thread is modifying the contents of the . this function will 2block until the other thread finishes its action. 1Like 0 but doesn't block. Returns ; the result if read access $could be acquired without blocking, : otherwise. 2Modify the contents of an .. 2This function needs exclusive write access to the .. Only one thread can  modify an .* at the same time. All others will block. 3Modify the contents of an .! and return an additional value. Like 2%, but allows a value to be returned () in addition to the modified value of the .. 4%Attempt to modify the contents of an .. Like 2 , but doesn't block. Returns K if the contents could be  replaced, @ otherwise. 5%Attempt to modify the contents of an .! and return an additional value. Like 3 , but doesn't block. Returns ; the additional value if the contents could be replaced, : otherwise. OP./012345./012345./012345Q           !"#$%& '()*+,-.,/0,12,13+4567589:;<=>56?@A&BCDconcurrent-extra-0.1Control.Concurrent.LockControl.Concurrent.RLockControl.Concurrent.EventControl.Concurrent.STM.Event Control.Concurrent.ReadWriteLockControl.Concurrent.ReadWriteVarLocknew newAcquiredacquire tryAcquirereleasewithtryWithlockedRLockrecursionLevelStateSetClearedEventwait waitTimeoutsetclearstateRWLock acquireReadtryAcquireRead releaseReadwithRead tryWithRead acquireWritetryAcquireWrite releaseWrite withWrite tryWithWriteRWVarmodify_modify tryModify_ tryModifyunbaseControl.ApplicativeliftA2Control.Exception.Basebracket_ Data.MaybeNothingJustunEventghc-primGHC.BoolFalse GHC.TypesIntWriteReadFreereadLock writeLockTrue moduleNamevoid modifyIORefM modifyIORefM_