Skip to main content

MonitorGuard

Struct MonitorGuard 

Source
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>

Source

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));
Source

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
§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);

Trait Implementations§

Source§

impl<T> Deref for MonitorGuard<'_, T>

Source§

fn deref(&self) -> &Self::Target

Returns an immutable reference to the protected state.

Source§

type Target = T

The resulting type after dereferencing.
Source§

impl<T> DerefMut for MonitorGuard<'_, T>

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Returns a mutable reference to the protected state.

Auto Trait Implementations§

§

impl<'a, T> Freeze for MonitorGuard<'a, T>

§

impl<'a, T> RefUnwindSafe for MonitorGuard<'a, T>

§

impl<'a, T> !Send for MonitorGuard<'a, T>

§

impl<'a, T> Sync for MonitorGuard<'a, T>
where T: Sync + Send,

§

impl<'a, T> Unpin for MonitorGuard<'a, T>

§

impl<'a, T> UnsafeUnpin for MonitorGuard<'a, T>

§

impl<'a, T> UnwindSafe for MonitorGuard<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.