Struct maitake_sync::WaitCell

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

An atomically registered Waker.

This cell stores the Waker of a single task. A Waker is stored in the cell either by calling poll_wait, or by polling a wait future. Once a task’s Waker is stored in a WaitCell, it can be woken by calling wake on the WaitCell.

§Implementation Notes

This is inspired by the AtomicWaker type used in Tokio’s synchronization primitives, with the following modifications:

Implementations§

source§

impl WaitCell

source

pub const fn new() -> Self

Returns a new WaitCell, with no Waker stored in it.

source§

impl WaitCell

source

pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<Result<(), PollWaitError>>

Poll to wait on this WaitCell, consuming a stored wakeup or registering the Waker from the provided Context to be woken by the next wakeup.

Once a Waker has been registered, a subsequent call to wake will wake that Waker.

§Returns
source

pub fn wait(&self) -> Wait<'_>

Wait to be woken up by this cell.

§Returns

This future completes with the following values:

Note: The calling task’s Waker is not registered until AFTER the first time the returned Wait future is polled. This means that if a call to wake occurs between when wait is called and when the future is first polled, the future will not complete. If the caller is responsible for performing an operation which will result in an eventual wakeup, prefer calling subscribe before performing that operation and .awaiting the Wait future returned by subscribe.

source

pub fn subscribe(&self) -> Subscribe<'_>

Eagerly subscribe to notifications from this WaitCell.

This method returns a Subscribe Future, which outputs a Wait Future. Awaiting the Subscribe future will eagerly register the calling task to be woken by this WaitCell, so that the returned Wait future will be woken by any calls to wake (or close) that occur between when the Subscribe future completes and when the returned Wait future is .awaited.

This is primarily intended for scenarios where the task that waits on a WaitCell is responsible for performing some operation that ultimately results in the WaitCell being woken. If the task were to simply perform the operation and then call wait on the WaitCell, a potential race condition could occur where the operation completes and wakes the WaitCell before the Wait future is first .awaited. Using subscribe, the task can ensure that it is ready to be woken by the cell before performing an operation that could result in it being woken.

These scenarios occur when a wakeup is triggered by another thread/CPU core in response to an operation performed in the task waiting on the WaitCell, or when the wakeup is triggered by a hardware interrupt resulting from operations performed in the task.

§Examples
use maitake_sync::WaitCell;

// Perform an operation that results in a concurrent wakeup, such as
// unmasking an interrupt.
fn do_something_that_causes_a_wakeup() {
    // ...
}

static WAIT_CELL: WaitCell = WaitCell::new();

// Subscribe to notifications from the cell *before* calling
// `do_something_that_causes_a_wakeup()`, to ensure that we are
// ready to be woken when the interrupt is unmasked.
let wait = WAIT_CELL.subscribe().await;

// Actually perform the operation.
do_something_that_causes_a_wakeup();

// Wait for the wakeup. If the wakeup occurred *before* the first
// poll of the `wait` future had successfully subscribed to the
// `WaitCell`, we would still receive the wakeup, because the
// `subscribe` future ensured that our waker was registered to be
// woken.
wait.await.expect("WaitCell is not closed");
source

pub fn wake(&self) -> bool

Wake the Waker stored in this cell.

§Returns
  • true if a waiting task was woken.
  • false if no task was woken (no Waker was stored in the cell)
source

pub fn close(&self) -> bool

Close the WaitCell.

This wakes any waiting task with an error indicating the WaitCell is closed. Subsequent calls to wait or poll_wait will return an error indicating that the cell has been closed.

Trait Implementations§

source§

impl Debug for WaitCell

source§

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

Formats the value using the given formatter. Read more
source§

impl Drop for WaitCell

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl Send for WaitCell

source§

impl Sync for WaitCell

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.