pub struct MonitorGuard<'a, T> { /* private fields */ }Expand description
Guard returned by Monitor::lock.
MonitorGuard is the monitor-specific counterpart of
std::sync::MutexGuard. While it exists, the protected state is locked.
Dropping the guard releases the lock. It implements Deref and
DerefMut, so callers can read and mutate the protected state as if they
held &T or &mut T.
Unlike a raw MutexGuard, this guard also remembers the monitor that
created it. That lets Self::wait and Self::wait_timeout release and
reacquire the correct mutex with the correct condition variable.
§Type Parameters
T- The state protected by the monitor.
§Example
use qubit_lock::lock::Monitor;
let monitor = Monitor::new(Vec::new());
{
let mut items = monitor.lock();
items.push("first");
}
assert_eq!(monitor.read(|items| items.len()), 1);Implementations§
Source§impl<'a, T> MonitorGuard<'a, T>
impl<'a, T> MonitorGuard<'a, T>
Sourcepub fn wait(self) -> Self
pub fn wait(self) -> Self
Waits for a notification while temporarily releasing the monitor lock.
This method consumes the current guard, calls the underlying
std::sync::Condvar::wait, and returns a new guard after the lock has
been reacquired. It is intended for explicit guarded-suspension loops
where the caller needs to inspect or update state before and after
waiting.
The method may block indefinitely if no notification is sent. The wait may also wake spuriously, so callers should use it inside a loop that re-checks the protected state.
If the mutex is poisoned while waiting, the poisoned state is recovered and returned in the new guard.
§Returns
A new guard holding the monitor lock after the wait returns.
§Example
use std::{
sync::Arc,
thread,
};
use qubit_lock::lock::Monitor;
let monitor = Arc::new(Monitor::new(false));
let waiter_monitor = Arc::clone(&monitor);
let waiter = thread::spawn(move || {
let mut ready = waiter_monitor.lock();
while !*ready {
ready = ready.wait();
}
*ready = false;
});
{
let mut ready = monitor.lock();
*ready = true;
}
monitor.notify_one();
waiter.join().expect("waiter should finish");
assert!(!monitor.read(|ready| *ready));Sourcepub fn wait_timeout(self, timeout: Duration) -> (Self, WaitTimeoutStatus)
pub fn wait_timeout(self, timeout: Duration) -> (Self, WaitTimeoutStatus)
Waits for a notification or timeout while temporarily releasing the lock.
This method consumes the current guard, calls the underlying
std::sync::Condvar::wait_timeout, and returns a new guard after the
lock has been reacquired. The status reports whether the wait reached
the timeout boundary or returned earlier.
A WaitTimeoutStatus::Woken result does not prove that another thread
changed the state; condition variables may wake spuriously. A
WaitTimeoutStatus::TimedOut result also does not remove the need to
inspect the state, because another thread may have changed it while this
thread was reacquiring the lock.
If the mutex is poisoned while waiting, the poisoned state is recovered and returned in the new guard.
§Arguments
timeout- Maximum duration to wait before returningWaitTimeoutStatus::TimedOut.
§Returns
A tuple containing the reacquired guard and the timed-wait status.
§Example
use std::time::Duration;
use qubit_lock::lock::{Monitor, WaitTimeoutStatus};
let monitor = Monitor::new(0);
let guard = monitor.lock();
let (guard, status) = guard.wait_timeout(Duration::from_millis(1));
assert_eq!(*guard, 0);
assert_eq!(status, WaitTimeoutStatus::TimedOut);