Copyright | © 2010-2011 Bas van Dijk & Roel van Dijk © 2018 DFINITY Stiftung |
---|---|
Maintainer | DFINITY USA Research <team@dfinity.org> |
Safe Haskell | None |
Language | Haskell2010 |
This module provides the Lock
synchronisation mechanism. It was inspired by
the Python and Java Lock
objects and should behave in a similar way. See:
http://docs.python.org/3.1/library/threading.html#lock-objects
and:
http://java.sun.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html
All functions are exception safe. Throwing asynchronous exceptions will not
compromise the internal state of a Lock
.
Synopsis
- data Lock m
- newLock :: MonadConc m => m (Lock m)
- newAcquired :: MonadConc m => m (Lock m)
- acquire :: MonadConc m => Lock m -> m ()
- tryAcquire :: MonadConc m => Lock m -> m Bool
- release :: MonadConc m => Lock m -> m ()
- with :: MonadConc m => Lock m -> m a -> m a
- tryWith :: MonadConc m => Lock m -> m a -> m (Maybe a)
- wait :: MonadConc m => Lock m -> m ()
- locked :: MonadConc m => Lock m -> m Bool
Lock
A lock is in one of two states: "locked" or "unlocked".
Since: 1.6.2.0
Creating locks
newAcquired :: MonadConc m => m (Lock m) Source #
Create a lock in the "locked" state.
Since: 1.6.2.0
Locking and unlocking
acquire :: MonadConc m => Lock m -> m () Source #
Acquires the Lock
. Blocks if another thread has acquired the Lock
.
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 torelease
in another thread wakes the calling thread. Upon awakening it will change the state to "locked".
There are two further important properties of acquire
:
acquire
is single-wakeup. That is, if there are multiple threads blocked onacquire
and the lock is released, only one thread will be woken up. The runtime guarantees that the woken thread completes itsacquire
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.
Since: 1.6.2.0
tryAcquire :: MonadConc m => Lock m -> m Bool Source #
A non-blocking acquire
.
- When the state is "unlocked"
tryAcquire
changes the state to "locked" and returnsTrue
. - When the state is "locked"
tryAcquire
leaves the state unchanged and returnsFalse
.
Since: 1.6.2.0
release :: MonadConc m => Lock m -> m () Source #
release
changes the state to "unlocked" and returns immediately.
Note that it is an error to release a lock in the "unlocked" state!
If there are any threads blocked on acquire
the thread that first called
acquire
will be woken up.
Since: 1.6.2.0
Convenience functions
tryWith :: MonadConc m => Lock m -> m a -> m (Maybe a) Source #
A non-blocking with
. tryWith
is a convenience function which first tries
to acquire the lock. If that fails, Nothing
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 Just
the
result of the computation is returned.
Since: 1.6.2.0
wait :: MonadConc m => Lock m -> m () Source #
- When the state is "locked",
wait
blocks until a call torelease
in another thread changes it to "unlocked". wait
is multiple-wakeup, so when multiple waiters are blocked on aLock
, all of them are woken up at the same time.- When the state is "unlocked"
wait
returns immediately.
wait
does not alter the state of the lock.
Since: 1.6.2.0