Skip to content
CryoCryo home
Stdlibfuture

waker

import std::future::waker; · source

Types

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.

Properties

PropertyType
wakerWaker

Constructors

static new(waker: Waker) -> Context;

Methods

waker(&this) -> Waker;

An owned clone of the current task's waker, ready to store past this poll. Runs the waker's clone_fn (a refcount bump for an owning waker), so the caller owns the returned waker and must drop it; a plain copy of the field would alias one clone_fn under two drop_fns.

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.

Properties

PropertyType
datau8*

Constructors

static noop() -> Waker;

A waker that does nothing when woken. Used by drivers (like block_on) that re-poll unconditionally and never park a task.

static new(wake_fn: (u8*) -> void, clone_fn: (u8*) -> u8*, drop_fn: (u8*) -> void, data: u8*) -> Waker;

Build a waker from its vtable and context pointer. wake_fn reschedules the task named by data; clone_fn duplicates the data handle; drop_fn releases it.

static new_nonowning(wake_fn: (u8*) -> void, data: u8*) -> Waker;

Build a non-owning waker: data is a borrowed pointer the executor keeps alive for the whole window this waker could fire, so cloning is a plain copy and dropping is a no-op. The common Phase-3 constructor (Phase-4 owned wakers use new with real clone_fn/drop_fn).

static take(slot: Waker*) -> Waker;

Move the waker out of slot, leaving a no-op behind. The caller owns the result: dropping it releases the share of a task the stored waker held.

static replace(slot: Waker*, w: Waker) -> Waker;

Store w in slot and hand back the waker that was there.

Methods

wake_fn: (u8*) -> void;
clone_fn: (u8*) -> u8*;
drop_fn: (u8*) -> void;
wake(&this) -> void;

Request that the associated task be polled again.

wake_by_ref(&this) -> void;

Wake without consuming the waker. Identical to wake for a non-owning waker; the distinction (avoiding an owned-waker drop) matters once wakers become refcounted in Phase 4. Present now to fix the call sites.

clone(&this) -> Waker;

Duplicate this waker. clone_fn produces the data handle for the copy (identity today; a refcount bump once wakers are owned). Use this rather than an implicit copy wherever a waker is stored, so Phase 4's move to a refcounted, non-Copy waker needs no change at the call site.

Trait implementations

implement trait Drop for struct Waker