pub struct ArcMonitor<T> { /* private fields */ }Expand description
Arc-wrapped monitor for shared condition-based state coordination.
ArcMonitor stores a Monitor behind an Arc, so callers can clone
the monitor handle directly without writing Arc::new(Monitor::new(...)).
It preserves the same guard-based waiting, predicate-based waiting, and
poison recovery semantics as Monitor.
§Type Parameters
T- The state protected by this monitor.
§Example
use std::thread;
use qubit_lock::lock::ArcMonitor;
let monitor = ArcMonitor::new(false);
let waiter_monitor = monitor.clone();
let waiter = thread::spawn(move || {
waiter_monitor.wait_until(
|ready| *ready,
|ready| {
*ready = false;
},
);
});
monitor.write(|ready| {
*ready = true;
});
monitor.notify_all();
waiter.join().expect("waiter should finish");
assert!(!monitor.read(|ready| *ready));§Author
Haixing Hu
Implementations§
Source§impl<T> ArcMonitor<T>
impl<T> ArcMonitor<T>
Sourcepub fn lock(&self) -> MonitorGuard<'_, T>
pub fn lock(&self) -> MonitorGuard<'_, T>
Acquires the shared monitor and returns a guard.
This delegates to Monitor::lock. The returned MonitorGuard
keeps the monitor mutex locked until it is dropped. It can also wait on
the monitor’s condition variable through MonitorGuard::wait or
MonitorGuard::wait_timeout.
If the underlying mutex is poisoned, this method recovers the inner state and still returns a guard.
§Returns
A guard that provides read and write access to the protected state.
§Example
use qubit_lock::lock::ArcMonitor;
let monitor = ArcMonitor::new(1);
{
let mut value = monitor.lock();
*value += 1;
}
assert_eq!(monitor.read(|value| *value), 2);Sourcepub fn read<R, F>(&self, f: F) -> R
pub fn read<R, F>(&self, f: F) -> R
Acquires the monitor and reads the protected state.
This delegates to Monitor::read. The closure runs while the monitor
mutex is held, so keep it short and avoid long blocking work.
§Arguments
f- Closure that receives an immutable reference to the state.
§Returns
The value returned by f.
Sourcepub fn write<R, F>(&self, f: F) -> R
pub fn write<R, F>(&self, f: F) -> R
Acquires the monitor and mutates the protected state.
This delegates to Monitor::write. Callers should explicitly invoke
Self::notify_one or Self::notify_all after changing state that a
waiting thread may observe.
§Arguments
f- Closure that receives a mutable reference to the state.
§Returns
The value returned by f.
Sourcepub fn wait_notify(&self, timeout: Duration) -> WaitTimeoutStatus
pub fn wait_notify(&self, timeout: Duration) -> WaitTimeoutStatus
Waits for a notification or timeout without checking state.
This delegates to Monitor::wait_notify. Most
coordination code should prefer Self::wait_while,
Self::wait_until, or an explicit MonitorGuard loop.
Condition variables may wake spuriously, so
WaitTimeoutStatus::Woken does not prove that a notifier changed the
state.
§Arguments
timeout- Maximum duration to wait for a notification.
§Returns
WaitTimeoutStatus::Woken if the wait returned before the timeout,
or WaitTimeoutStatus::TimedOut if the timeout elapsed.
§Example
use std::time::Duration;
use qubit_lock::lock::{ArcMonitor, WaitTimeoutStatus};
let monitor = ArcMonitor::new(false);
let status = monitor.wait_notify(Duration::from_millis(1));
assert_eq!(status, WaitTimeoutStatus::TimedOut);Sourcepub fn wait_while<R, P, F>(&self, waiting: P, f: F) -> R
pub fn wait_while<R, P, F>(&self, waiting: P, f: F) -> R
Waits while a predicate remains true, then mutates the protected state.
This delegates to Monitor::wait_while. The predicate is evaluated
while holding the monitor mutex, and the closure runs while the mutex is
still held after the predicate stops blocking.
This method may block indefinitely if no thread changes the state so
that waiting becomes false and sends a notification.
§Arguments
waiting- Predicate that returnstruewhile the caller should keep waiting.f- Closure that receives mutable access after waiting is no longer required.
§Returns
The value returned by f.
§Example
use std::thread;
use qubit_lock::lock::ArcMonitor;
let monitor = ArcMonitor::new(Vec::<i32>::new());
let worker_monitor = monitor.clone();
let worker = thread::spawn(move || {
worker_monitor.wait_while(
|items| items.is_empty(),
|items| items.pop().expect("item should be ready"),
)
});
monitor.write(|items| items.push(7));
monitor.notify_one();
assert_eq!(worker.join().expect("worker should finish"), 7);Sourcepub fn wait_until<R, P, F>(&self, ready: P, f: F) -> R
pub fn wait_until<R, P, F>(&self, ready: P, f: F) -> R
Waits until the protected state satisfies a predicate, then mutates it.
This delegates to Monitor::wait_until. It may block indefinitely if
no thread changes the state to satisfy the predicate and sends a
notification.
§Arguments
ready- Predicate that returnstruewhen the state is ready.f- Closure that receives mutable access to the ready state.
§Returns
The value returned by f.
Sourcepub fn wait_timeout_while<R, P, F>(
&self,
timeout: Duration,
waiting: P,
f: F,
) -> WaitTimeoutResult<R>
pub fn wait_timeout_while<R, P, F>( &self, timeout: Duration, waiting: P, f: F, ) -> WaitTimeoutResult<R>
Waits while a predicate remains true, with an overall time limit.
This delegates to Monitor::wait_timeout_while. If waiting becomes
false before timeout expires, f runs while the monitor lock is still
held. If the timeout expires first, the closure is not called.
§Arguments
timeout- Maximum total duration to wait.waiting- Predicate that returnstruewhile the caller should continue waiting.f- Closure that receives mutable access when waiting is no longer required.
§Returns
WaitTimeoutResult::Ready with the value returned by f when the
predicate stops blocking before the timeout. Returns
WaitTimeoutResult::TimedOut when the timeout expires first.
§Example
use std::time::Duration;
use qubit_lock::lock::{ArcMonitor, WaitTimeoutResult};
let monitor = ArcMonitor::new(Vec::<i32>::new());
let result = monitor.wait_timeout_while(
Duration::from_millis(1),
|items| items.is_empty(),
|items| items.pop(),
);
assert_eq!(result, WaitTimeoutResult::TimedOut);Sourcepub fn wait_timeout_until<R, P, F>(
&self,
timeout: Duration,
ready: P,
f: F,
) -> WaitTimeoutResult<R>
pub fn wait_timeout_until<R, P, F>( &self, timeout: Duration, ready: P, f: F, ) -> WaitTimeoutResult<R>
Waits until a predicate becomes true, with an overall time limit.
This delegates to Monitor::wait_timeout_until. If ready becomes
true before timeout expires, f runs while the monitor lock is still
held. If the timeout expires first, the closure is not called.
§Arguments
timeout- Maximum total duration to wait.ready- Predicate that returnstruewhen the caller may continue.f- Closure that receives mutable access to the ready state.
§Returns
WaitTimeoutResult::Ready with the value returned by f when the
predicate becomes true before the timeout. Returns
WaitTimeoutResult::TimedOut when the timeout expires first.
§Example
use std::{
thread,
time::Duration,
};
use qubit_lock::lock::{ArcMonitor, WaitTimeoutResult};
let monitor = ArcMonitor::new(false);
let worker_monitor = monitor.clone();
let worker = thread::spawn(move || {
worker_monitor.wait_timeout_until(
Duration::from_secs(1),
|ready| *ready,
|ready| {
*ready = false;
5
},
)
});
monitor.write(|ready| *ready = true);
monitor.notify_one();
assert_eq!(
worker.join().expect("worker should finish"),
WaitTimeoutResult::Ready(5),
);Sourcepub fn notify_one(&self)
pub fn notify_one(&self)
Wakes one thread waiting in Self::wait_until.
Notifications do not carry state by themselves. A waiting thread only proceeds when its predicate observes the protected state as ready.
Sourcepub fn notify_all(&self)
pub fn notify_all(&self)
Wakes all threads waiting in Self::wait_until.
Every awakened thread rechecks its predicate before continuing.
Trait Implementations§
Source§impl<T> Clone for ArcMonitor<T>
impl<T> Clone for ArcMonitor<T>
Source§fn clone(&self) -> Self
fn clone(&self) -> Self
Clones this monitor handle.
The cloned handle shares the same protected state and condition variable with the original.
§Returns
A new handle sharing the same monitor state.
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more