Crate async_event

Source
Expand description

An efficient async condition variable for lock-free algorithms, a.k.a. “eventcount”.

Eventcount-like primitives are useful to make some operations on a lock-free structure blocking, for instance to transform bounded queues into bounded channels. Such a primitive allows an interested task to block until a predicate is satisfied by checking the predicate each time it receives a notification.

While functionally similar to the event_listener crate, this implementation is more opinionated and limited to the async case. It strives to be more efficient, however, by limiting the amount of locking operations on the mutex-protected list of notifiers: the lock is typically taken only once for each time a waiter is blocked and once for notifying, thus reducing the need for synchronization operations. Finally, spurious wake-ups are only generated in very rare circumstances.

This library is an offshoot of Asynchronix, an ongoing effort at a high performance asynchronous computation framework for system simulation.

§Examples

Wait until a non-zero value has been sent asynchronously.

use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::thread;

use futures_executor::block_on;

use async_event::Event;


let value = Arc::new(AtomicUsize::new(0));
let event = Arc::new(Event::new());

// Set a non-zero value concurrently.
thread::spawn({
    let value = value.clone();
    let event = event.clone();

    move || {
        // A relaxed store is sufficient here: `Event::notify*` methods insert
        // atomic fences to warrant adequate synchronization.
        value.store(42, Ordering::Relaxed);
        event.notify_one();
    }
});

// Wait until the value is set.
block_on(async move {
    let v = event
        .wait_until(|| {
            // A relaxed load is sufficient here: `Event::wait_until` inserts
            // atomic fences to warrant adequate synchronization.
            let v = value.load(Ordering::Relaxed);
            if v != 0 { Some(v) } else { None }
        })
        .await;

     assert_eq!(v, 42);
});

Structs§

Event
An object that can receive or send notifications.
WaitUntil
A future that can be awaited until a predicate is satisfied.
WaitUntilOrTimeout
A future that can be awaited until a predicate is satisfied or until a deadline elapses.