Skip to content
CryoCryo home
Stdlibfuture

waker

import std::future::waker; · source

Context

type struct Context {
    waker: Waker;

    static new(waker: Waker) -> Context;
    waker(&this) -> Waker;
}

A future is polled with a Context, which carries the Waker for the task being polled — today that is all it carries, and waker() hands it out.

Waker

type struct Waker {
    wake_fn: (u8*) -> void;
    clone_fn: (u8*) -> u8*;
    drop_fn: (u8*) -> void;

    data: u8*;

    static noop() -> Waker;
    static new(wake_fn: (u8*) -> void, clone_fn: (u8*) -> u8*, drop_fn: (u8*) -> void, data: u8*) -> Waker;
    static new_nonowning(wake_fn: (u8*) -> void, data: u8*) -> Waker;
    wake(&this) -> void;
    wake_by_ref(&this) -> void;
    clone(&this) -> Waker;
    static take(slot: Waker*) -> Waker;
    static replace(slot: Waker*, w: Waker) -> Waker;
}

A leaf future that cannot make progress clones the waker from its Context, hands it to the reactor or the blocking pool, and returns Pending; whoever holds the clone calls wake() when the future should be polled again.

Waker is built on the same non-capturing-function-pointer plus void* erasure that catch_unwind and thread::spawn use: a three-entry manual vtable and a data pointer. The executor's wakers point at a reference-counted task, so clone bumps the count and drop releases it, which is what keeps a parked task alive.

  • new_nonowning builds a waker whose clone and drop are no-ops, for a waker that points at something with its own lifetime.
  • take and replace move a waker in and out of a slot without an intermediate drop — a future that stores the waker it was last polled with uses them to swap.
  • noop() is a waker that does nothing, for polling a future by hand in a test.

Trait implementations

implement trait Drop for struct Waker