pub struct Notify { /* private fields */ }
Expand description

Notifies a single task to wake up.

Notify provides a basic mechanism to notify a single task of an event. Notify itself does not carry any data. Instead, it is to be used to signal another task to perform an operation.

Notify can be thought of as a Semaphore starting with 0 permits. notified().await waits for a permit to become available, and notify_one() sets a permit if there currently are no available permits.

The synchronization details of Notify are similar to thread::park and Thread::unpark from std. A Notify value contains a single permit. notified().await waits for the permit to be made available, consumes the permit, and resumes. notify_one() sets the permit, waking a pending task if there is one.

If notify_one() is called before notified().await, then the next call to notified().await will complete immediately, consuming the permit. Any subsequent calls to notified().await will wait for a new permit.

If notify_one() is called multiple times before notified().await, only a single permit is stored. The next call to notified().await will complete immediately, but the one after will wait for a new permit.

Examples

Basic usage.

use tokio::sync::Notify;
use std::sync::Arc;

#[tokio::main]
async fn main() {
    let notify = Arc::new(Notify::new());
    let notify2 = notify.clone();

    let handle = tokio::spawn(async move {
        notify2.notified().await;
        println!("received notification");
    });

    println!("sending notification");
    notify.notify_one();

    // Wait for task to receive notification.
    handle.await.unwrap();
}

Unbound mpsc channel.

use tokio::sync::Notify;

use std::collections::VecDeque;
use std::sync::Mutex;

struct Channel<T> {
    values: Mutex<VecDeque<T>>,
    notify: Notify,
}

impl<T> Channel<T> {
    pub fn send(&self, value: T) {
        self.values.lock().unwrap()
            .push_back(value);

        // Notify the consumer a value is available
        self.notify.notify_one();
    }

    pub async fn recv(&self) -> T {
        loop {
            // Drain values
            if let Some(value) = self.values.lock().unwrap().pop_front() {
                return value;
            }

            // Wait for values to be available
            self.notify.notified().await;
        }
    }
}

Implementations

Create a new Notify, initialized without a permit.

Examples
use tokio::sync::Notify;

let notify = Notify::new();

Create a new Notify, initialized without a permit.

Examples
use tokio::sync::Notify;

static NOTIFY: Notify = Notify::const_new();

Wait for a notification.

Equivalent to:

async fn notified(&self);

Each Notify value holds a single permit. If a permit is available from an earlier call to notify_one(), then notified().await will complete immediately, consuming that permit. Otherwise, notified().await waits for a permit to be made available by the next call to notify_one().

Cancel safety

This method uses a queue to fairly distribute notifications in the order they were requested. Cancelling a call to notified makes you lose your place in the queue.

Examples
use tokio::sync::Notify;
use std::sync::Arc;

#[tokio::main]
async fn main() {
    let notify = Arc::new(Notify::new());
    let notify2 = notify.clone();

    tokio::spawn(async move {
        notify2.notified().await;
        println!("received notification");
    });

    println!("sending notification");
    notify.notify_one();
}

Notifies a waiting task.

If a task is currently waiting, that task is notified. Otherwise, a permit is stored in this Notify value and the next call to notified().await will complete immediately consuming the permit made available by this call to notify_one().

At most one permit may be stored by Notify. Many sequential calls to notify_one will result in a single permit being stored. The next call to notified().await will complete immediately, but the one after that will wait.

Examples
use tokio::sync::Notify;
use std::sync::Arc;

#[tokio::main]
async fn main() {
    let notify = Arc::new(Notify::new());
    let notify2 = notify.clone();

    tokio::spawn(async move {
        notify2.notified().await;
        println!("received notification");
    });

    println!("sending notification");
    notify.notify_one();
}

Notifies all waiting tasks.

If a task is currently waiting, that task is notified. Unlike with notify_one(), no permit is stored to be used by the next call to notified().await. The purpose of this method is to notify all already registered waiters. Registering for notification is done by acquiring an instance of the Notified future via calling notified().

Examples
use tokio::sync::Notify;
use std::sync::Arc;

#[tokio::main]
async fn main() {
    let notify = Arc::new(Notify::new());
    let notify2 = notify.clone();

    let notified1 = notify.notified();
    let notified2 = notify.notified();

    let handle = tokio::spawn(async move {
        println!("sending notifications");
        notify2.notify_waiters();
    });

    notified1.await;
    notified2.await;
    println!("received notifications");
}

Trait Implementations

Formats the value using the given formatter. Read more

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.