Struct async_std::sync::Condvar

source ·
pub struct Condvar { /* private fields */ }
Expand description

A Condition Variable

This type is an async version of std::sync::Condvar.

Examples

use std::sync::Arc;

use async_std::sync::{Mutex, Condvar};
use async_std::task;

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

// Inside of our lock, spawn a new thread, and then wait for it to start.
task::spawn(async move {
    let (lock, cvar) = &*pair2;
    let mut started = lock.lock().await;
    *started = true;
    // We notify the condvar that the value has changed.
    cvar.notify_one();
});

// Wait for the thread to start up.
let (lock, cvar) = &*pair;
let mut started = lock.lock().await;
while !*started {
    started = cvar.wait(started).await;
}

Implementations§

source§

impl Condvar

source

pub fn new() -> Self

Creates a new condition variable

Examples
use async_std::sync::Condvar;

let cvar = Condvar::new();
source

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

Blocks the current task until this condition variable receives a notification.

Unlike the std equivalent, this does not check that a single mutex is used at runtime. However, as a best practice avoid using with multiple mutexes.

Examples
use std::sync::Arc;

use async_std::sync::{Mutex, Condvar};
use async_std::task;

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

task::spawn(async move {
    let (lock, cvar) = &*pair2;
    let mut started = lock.lock().await;
    *started = true;
    // We notify the condvar that the value has changed.
    cvar.notify_one();
});

// Wait for the thread to start up.
let (lock, cvar) = &*pair;
let mut started = lock.lock().await;
while !*started {
    started = cvar.wait(started).await;
}
source

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

Blocks the current taks until this condition variable receives a notification and the required condition is met. Spurious wakeups are ignored and this function will only return once the condition has been met.

Examples
use std::sync::Arc;

use async_std::sync::{Mutex, Condvar};
use async_std::task;

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

task::spawn(async move {
    let (lock, cvar) = &*pair2;
    let mut started = lock.lock().await;
    *started = true;
    // We notify the condvar that the value has changed.
    cvar.notify_one();
});

// Wait for the thread to start up.
let (lock, cvar) = &*pair;
// As long as the value inside the `Mutex<bool>` is `false`, we wait.
let _guard = cvar.wait_until(lock.lock().await, |started| { *started }).await;
source

pub async fn wait_timeout<'a, T>( &self, guard: MutexGuard<'a, T>, dur: Duration ) -> (MutexGuard<'a, T>, WaitTimeoutResult)

Waits on this condition variable for a notification, timing out after a specified duration.

For these reasons Condvar::wait_timeout_until is recommended in most cases.

Examples
use std::sync::Arc;
use std::time::Duration;

use async_std::sync::{Mutex, Condvar};
use async_std::task;

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

task::spawn(async move {
  let (lock, cvar) = &*pair2;
  let mut started = lock.lock().await;
  *started = true;
  // We notify the condvar that the value has changed.
  cvar.notify_one();
});

// wait for the thread to start up
let (lock, cvar) = &*pair;
let mut started = lock.lock().await;
loop {
  let result = cvar.wait_timeout(started, Duration::from_millis(10)).await;
  started = result.0;
  if *started == true {
      // We received the notification and the value has been updated, we can leave.
      break
  }
}
source

pub async fn wait_timeout_until<'a, T, F>( &self, guard: MutexGuard<'a, T>, dur: Duration, condition: F ) -> (MutexGuard<'a, T>, WaitTimeoutResult)
where F: FnMut(&mut T) -> bool,

Waits on this condition variable for a notification, timing out after a specified duration. Spurious wakes will not cause this function to return.

Examples
use std::sync::Arc;
use std::time::Duration;

use async_std::sync::{Mutex, Condvar};
use async_std::task;

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

task::spawn(async move {
    let (lock, cvar) = &*pair2;
    let mut started = lock.lock().await;
    *started = true;
    // We notify the condvar that the value has changed.
    cvar.notify_one();
});

// wait for the thread to start up
let (lock, cvar) = &*pair;
let result = cvar.wait_timeout_until(
    lock.lock().await,
    Duration::from_millis(100),
    |&mut started| started,
).await;
if result.1.timed_out() {
    // timed-out without the condition ever evaluating to true.
}
// access the locked mutex via result.0
source

pub fn notify_one(&self)

Wakes up one blocked task on this condvar.

Examples
use std::sync::Arc;

use async_std::sync::{Mutex, Condvar};
use async_std::task;

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

task::spawn(async move {
    let (lock, cvar) = &*pair2;
    let mut started = lock.lock().await;
    *started = true;
    // We notify the condvar that the value has changed.
    cvar.notify_one();
});

// Wait for the thread to start up.
let (lock, cvar) = &*pair;
let mut started = lock.lock().await;
while !*started {
    started = cvar.wait(started).await;
}
source

pub fn notify_all(&self)

Wakes up all blocked tasks on this condvar.

Examples
use std::sync::Arc;

use async_std::sync::{Mutex, Condvar};
use async_std::task;

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

task::spawn(async move {
    let (lock, cvar) = &*pair2;
    let mut started = lock.lock().await;
    *started = true;
    // We notify the condvar that the value has changed.
    cvar.notify_all();
});

// Wait for the thread to start up.
let (lock, cvar) = &*pair;
let mut started = lock.lock().await;
// As long as the value inside the `Mutex<bool>` is `false`, we wait.
while !*started {
    started = cvar.wait(started).await;
}

Trait Implementations§

source§

impl Debug for Condvar

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
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.