#[repr(align(128))]
pub struct Condvar { state: AtomicUsize, waiters: UnsafeCell<LinkedList<WaiterAdapter>>, mu: UnsafeCell<usize>, }
Expand description

A primitive to wait for an event to occur without consuming CPU time.

Condition variables are used in combination with a Mutex when a thread wants to wait for some condition to become true. The condition must always be verified while holding the Mutex lock. It is an error to use a Condvar with more than one Mutex while there are threads waiting on the Condvar.

Examples

use std::sync::Arc;
use std::thread;
use std::sync::mpsc::channel;

use cros_async::{
    block_on,
    sync::{Condvar, Mutex},
};

const N: usize = 13;

// Spawn a few threads to increment a shared variable (non-atomically), and
// let all threads waiting on the Condvar know once the increments are done.
let data = Arc::new(Mutex::new(0));
let cv = Arc::new(Condvar::new());

for _ in 0..N {
    let (data, cv) = (data.clone(), cv.clone());
    thread::spawn(move || {
        let mut data = block_on(data.lock());
        *data += 1;
        if *data == N {
            cv.notify_all();
        }
    });
}

let mut val = block_on(data.lock());
while *val != N {
    val = block_on(cv.wait(val));
}

Fields

state: AtomicUsizewaiters: UnsafeCell<LinkedList<WaiterAdapter>>mu: UnsafeCell<usize>

Implementations

Creates a new condition variable ready to be waited on and notified.

Block the current thread until this Condvar is notified by another thread.

This method will atomically unlock the Mutex held by guard and then block the current thread. Any call to notify_one or notify_all after the Mutex is unlocked may wake up the thread.

To allow for more efficient scheduling, this call may return even when the programmer doesn’t expect the thread to be woken. Therefore, calls to wait() should be used inside a loop that checks the predicate before continuing.

Callers that are not in an async context may wish to use the block_on method to block the thread until the Condvar is notified.

Panics

This method will panic if used with more than one Mutex at the same time.

Examples




let mut ready = block_on(mu.lock());
while !*ready {
    ready = block_on(cv.wait(ready));
}

Like wait() but takes and returns a MutexReadGuard instead.

Notify at most one thread currently waiting on the Condvar.

If there is a thread currently waiting on the Condvar it will be woken up from its call to wait.

Unlike more traditional condition variable interfaces, this method requires a reference to the Mutex associated with this Condvar. This is because it is inherently racy to call notify_one or notify_all without first acquiring the Mutex lock. Additionally, taking a reference to the Mutex here allows us to make some optimizations that can improve performance by reducing unnecessary wakeups.

Notify all threads currently waiting on the Condvar.

All threads currently waiting on the Condvar will be woken up from their call to wait.

Unlike more traditional condition variable interfaces, this method requires a reference to the Mutex associated with this Condvar. This is because it is inherently racy to call notify_one or notify_all without first acquiring the Mutex lock. Additionally, taking a reference to the Mutex here allows us to make some optimizations that can improve performance by reducing unnecessary wakeups.

Trait Implementations

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

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.