Condvar

Struct Condvar 

Source
pub struct Condvar { /* private fields */ }
Expand description

A wrapper around a condition variable that tracks operations for deadlock detection

The Condvar provides the same interface as a standard condition variable but adds deadlock detection by tracking wait and notify operations. It’s a drop-in replacement for std::sync::Condvar that enables deadlock detection.

§Example

use deloxide::{Mutex, Condvar};
use std::sync::Arc;
use std::thread;

let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);

// Spawn a thread that waits for the condition
thread::spawn(move || {
    let (lock, cvar) = &*pair2;
    let mut started = lock.lock();
    while !*started {
        cvar.wait(&mut started);
    }
});

// Signal the condition in the main thread
let (lock, cvar) = &*pair;
let mut started = lock.lock();
*started = true;
cvar.notify_one();

Implementations§

Source§

impl Condvar

Source

pub fn new() -> Self

Create a new Condvar with an automatically assigned ID

§Returns

A new Condvar ready for use with deadlock detection

§Example
use deloxide::Condvar;

let condvar = Condvar::new();
Source

pub fn id(&self) -> LockId

Get the ID of this condition variable

§Returns

The unique identifier assigned to this condition variable

Source

pub fn wait<'a, T>(&self, guard: &mut MutexGuard<'a, T>)

Wait on this condition variable, releasing the associated mutex and blocking until another thread notifies this condition variable

This method will atomically unlock the mutex specified (represented by the guard) and block the current thread. This means that any calls to notify() which happen logically after the mutex is unlocked are candidates to wake this thread up. When this function call returns, the lock specified will have been re-acquired.

§Arguments
  • guard - A mutable reference to a MutexGuard that will be atomically unlocked
§Example
use deloxide::{Mutex, Condvar};
use std::sync::Arc;

let pair = Arc::new((Mutex::new(false), Condvar::new()));
let (lock, cvar) = &*pair;

// In a real application, you would use this in a loop:
// let mut guard = lock.lock();
// while !*guard {
//     cvar.wait(&mut guard);
// }
Source

pub fn wait_timeout<'a, T>( &self, guard: &mut MutexGuard<'a, T>, timeout: Duration, ) -> bool

Wait on this condition variable with a timeout

This method will atomically unlock the mutex specified (represented by the guard) and block the current thread. The thread will be blocked until another thread notifies this condition variable or until the timeout elapses. When this function returns, the lock specified will have been re-acquired.

§Arguments
  • guard - A mutable reference to a MutexGuard that will be atomically unlocked
  • timeout - The maximum duration to wait
§Returns

true if the timeout elapsed, false if the condition variable was notified

§Example
use deloxide::{Mutex, Condvar};
use std::sync::Arc;
use std::time::Duration;

let pair = Arc::new((Mutex::new(false), Condvar::new()));
let (lock, cvar) = &*pair;

let mut guard = lock.lock();
let timed_out = cvar.wait_timeout(&mut guard, Duration::from_millis(100));
if timed_out {
    println!("Timed out waiting for condition");
}
Source

pub fn wait_while<'a, T, F>(&self, guard: &mut MutexGuard<'a, T>, condition: F)
where F: FnMut(&mut T) -> bool,

Blocks the current thread until the provided condition becomes false

This is a convenience method that repeatedly calls wait while the condition returns true. It’s equivalent to a while loop with wait.

§Arguments
  • guard - A mutable reference to a MutexGuard
  • condition - A closure that returns true while waiting should continue
§Example
use deloxide::{Mutex, Condvar};
use std::sync::Arc;

let pair = Arc::new((Mutex::new(true), Condvar::new()));
let (lock, cvar) = &*pair;

let mut guard = lock.lock();
// Wait while the value is true (another thread would set it to false)
cvar.wait_while(&mut guard, |pending| *pending);
Source

pub fn wait_timeout_while<'a, T, F>( &self, guard: &mut MutexGuard<'a, T>, timeout: Duration, condition: F, ) -> bool
where F: FnMut(&mut T) -> bool,

Waits on this condition variable with a timeout while a condition is true

This is a convenience method that waits with a timeout while the condition returns true.

§Arguments
  • guard - A mutable reference to a MutexGuard
  • timeout - The maximum duration to wait
  • condition - A closure that returns true while waiting should continue
§Returns

true if the timeout elapsed, false if the condition became false

§Example
use deloxide::{Mutex, Condvar};
use std::sync::Arc;
use std::time::Duration;

let pair = Arc::new((Mutex::new(true), Condvar::new()));
let (lock, cvar) = &*pair;

let mut guard = lock.lock();
let timed_out = cvar.wait_timeout_while(
    &mut guard,
    Duration::from_millis(100),
    |pending| *pending
);
Source

pub fn notify_one(&self)

Wake up one blocked thread on this condition variable

If there is a blocked thread on this condition variable, then it will be woken up from its call to wait or wait_timeout. Calls to notify_one are not buffered in any way.

§Example
use deloxide::{Mutex, Condvar};
use std::sync::Arc;

let pair = Arc::new((Mutex::new(false), Condvar::new()));
let (lock, cvar) = &*pair;

// ... some other thread is waiting on cvar ...

let mut guard = lock.lock();
*guard = true;
drop(guard); // Release the lock before notifying
cvar.notify_one();
Source

pub fn notify_all(&self)

Wake up all blocked threads on this condition variable

All threads currently waiting on this condition variable will be woken up from their call to wait or wait_timeout. Calls to notify_all are not buffered in any way.

§Example
use deloxide::{Mutex, Condvar};
use std::sync::Arc;

let pair = Arc::new((Mutex::new(false), Condvar::new()));
let (lock, cvar) = &*pair;

// ... multiple threads are waiting on cvar ...

let mut guard = lock.lock();
*guard = true;
drop(guard); // Release the lock before notifying
cvar.notify_all();

Trait Implementations§

Source§

impl Default for Condvar

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Drop for Condvar

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

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

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V