Mutual exclusion primitive (a lock).
If you want to guard shared state, use Mutex α
instead.
Equations
Instances For
Creates a new BaseMutex
.
Locks a BaseMutex
. Waits until no other thread has locked the mutex.
The current thread must not have already locked the mutex.
Reentrant locking is undefined behavior (inherited from the C++ implementation).
If this is unavoidable in your code, consider using BaseRecursiveMutex
.
Attempts to lock a BaseMutex
. If the mutex is not available return false
, otherwise lock it and
return true
.
This function does not block.
The current thread must not have already locked the mutex.
Reentrant locking is undefined behavior (inherited from the C++ implementation).
If this is unavoidable in your code, consider using BaseRecursiveMutex
.
Unlocks a BaseMutex
.
The current thread must have already locked the mutex.
Unlocking an unlocked mutex is undefined behavior (inherited from the C++ implementation).
If this is unavoidable in your code, consider using BaseRecursiveMutex
.
Condition variable, a synchronization primitive to be used with a BaseMutex
or Mutex
.
The thread that wants to modify the shared variable must:
- Lock the
BaseMutex
orMutex
- Work on the shared variable
- Call
Condvar.notifyOne
orCondvar.notifyAll
after it is done. Note that this may be done before or after the mutex is unlocked.
If working with a Mutex
the thread that waits on the Condvar
can use Mutex.atomicallyOnce
to wait until a condition is true. If working with a BaseMutex
it must:
- Lock the
BaseMutex
. - Do one of the following:
- Use
Condvar.waitUntil
to (potentially repeatedly wait) on the condition variable until the condition is true. - Implement the waiting manually by:
- Checking the condition
- Calling
Condvar.wait
which releases theBaseMutex
and suspends execution until the condition variable is notified. - Check the condition and resume waiting if not satisfied.
Equations
Instances For
Creates a new condition variable.
Equations
- Std.instCoeOutMutexBaseMutex = { coe := Std.Mutex.mutex }
Creates a new mutex.
Equations
- Std.Mutex.new a = do let __do_lift ← IO.mkRef a let __do_lift_1 ← Std.BaseMutex.new pure { ref := __do_lift, mutex := __do_lift_1 }
Instances For
mutex.atomically k
runs k
with access to the mutex's state while locking the mutex.
Calling mutex.atomically
while already holding the underlying BaseMutex
in the same thread
is undefined behavior. If this is unavoidable in your code, consider using RecursiveMutex
.
Equations
- mutex.atomically k = tryFinally (do liftM mutex.mutex.lock k (Std.Mutex.ref✝ mutex)) (liftM mutex.mutex.unlock)
Instances For
mutex.tryAtomically k
tries to lock mutex
and runs k
on it if it succeeds. On success the
return value of k
is returned as some
, on failure none
is returned.
This function does not block on the mutex
. Additionally calling mutex.tryAtomically
while
already holding the underlying BaseMutex
in the same thread is undefined behavior. If this is
unavoidable in your code, consider using RecursiveMutex
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
mutex.atomicallyOnce condvar pred k
runs k
, waiting on condvar
until pred
returns true.
Both k
and pred
have access to the mutex's state.
Calling mutex.atomicallyOnce
while already holding the underlying BaseMutex
in the same thread
is undefined behavior. If this is unavoidable in your code, consider using RecursiveMutex
.
Equations
- mutex.atomicallyOnce condvar pred k = mutex.atomically do condvar.waitUntil mutex.mutex pred k