Struct cros_async::sync::Condvar

source ·
#[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 RwLock when a thread wants to wait for some condition to become true. The condition must always be verified while holding the RwLock lock. It is an error to use a Condvar with more than one RwLock 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, RwLock},
};

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(RwLock::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: AtomicUsize§waiters: UnsafeCell<LinkedList<WaiterAdapter>>§mu: UnsafeCell<usize>

Implementations§

source§

impl Condvar

source

pub fn new() -> Condvar

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

source

pub async fn wait<'g, T>( &self, guard: RwLockWriteGuard<'g, T> ) -> RwLockWriteGuard<'g, T>

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

This method will atomically unlock the RwLock held by guard and then block the current thread. Any call to notify_one or notify_all after the RwLock 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 RwLock at the same time.

§Examples




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

pub async fn wait_read<'g, T>( &self, guard: RwLockReadGuard<'g, T> ) -> RwLockReadGuard<'g, T>

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

source

fn add_waiter(&self, waiter: Arc<Waiter>, raw_rwlock: &RawRwLock)

source

pub fn notify_one(&self)

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 RwLock associated with this Condvar. This is because it is inherently racy to call notify_one or notify_all without first acquiring the RwLock lock. Additionally, taking a reference to the RwLock here allows us to make some optimizations that can improve performance by reducing unnecessary wakeups.

source

pub fn notify_all(&self)

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 RwLock associated with this Condvar. This is because it is inherently racy to call notify_one or notify_all without first acquiring the RwLock lock. Additionally, taking a reference to the RwLock here allows us to make some optimizations that can improve performance by reducing unnecessary wakeups.

source

fn cancel_waiter(&self, waiter: &Waiter, wake_next: bool)

Trait Implementations§

source§

impl Default for Condvar

source§

fn default() -> Self

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

impl Send for Condvar

source§

impl Sync for Condvar

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

§

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

§

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.