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
| Property | Type |
|---|---|
waker | Waker |
Constructors
static new(waker: Waker) -> Context;
Methods
waker(&this) -> Waker;
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_nonowningbuilds a waker whose clone and drop are no-ops, for a waker that points at something with its own lifetime.takeandreplacemove 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
| Property | Type |
|---|---|
data | u8* |
Constructors
static noop() -> Waker;
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;
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;
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;
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;
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;
wake(&this) -> void;Request that the associated task be polled again.
wake_by_ref(&this) -> void;
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;
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
type struct Name { ... }
type enum Name { ... }
type trait Name { ... }
type union Name { ... }Begins a type declaration; the keyword that follows says which kind. On its own, type Name = Existing; declares an alias.
type struct Name {
field: Type;
method(&this) -> Ret { ... }
}A value type with named fields and optional methods. Structs live on the stack and are passed by value. Fields are public by default and may carry = default values; methods take their receiver as &this, mut &this, or this.
type struct Context {
waker: Waker;
}The context threaded through a poll call. Holds the Waker a future registers when it returns Pending. Passed by pointer down the poll tree, matching the stdlib convention of moving aggregates by pointer.
Context.waker: Wakertype struct Waker {
data: u8*;
}A handle a stalled future stores so it can be re-scheduled: wake_fn(data) tells the executor "poll my task again". This is the manual-vtable shape used throughout the runtime — non-capturing function pointers plus an opaque data pointer identifying the task.
static name(param: Type) -> Ret { ... }A method that belongs to the type rather than an instance, called as Type::name(..). For structs, static new(..) returning a struct literal is the idiomatic constructor.
static Context::new(waker: Waker) -> Context(parameter) waker: Wakertype struct Context {
waker: Waker;
}The context threaded through a poll call. Holds the Waker a future registers when it returns Pending. Passed by pointer down the poll tree, matching the stdlib convention of moving aggregates by pointer.
&this
mut &this
thisThe receiver of a method. Its first parameter declares how the method takes it: &this borrows read-only, mut &this borrows exclusively, and this / mut this move the value in and consume it. In the body, this.field reaches the members.
type struct Waker {
data: u8*;
}A handle a stalled future stores so it can be re-scheduled: wake_fn(data) tells the executor "poll my task again". This is the manual-vtable shape used throughout the runtime — non-capturing function pointers plus an opaque data pointer identifying the task.
Waker::wake_fn: (u8*) -> voidWaker::clone_fn: (u8*) -> u8*Waker::drop_fn: (u8*) -> voidWaker.data: u8*static Waker::noop() -> WakerA waker that does nothing when woken. Used by drivers (like block_on) that re-poll unconditionally and never park a task.
static Waker::new(wake_fn: (u8*) -> void, clone_fn: (u8*) -> u8*, drop_fn: (u8*) -> void, data: u8*) -> WakerBuild 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.
(parameter) wake_fn: (u8*) -> void(parameter) clone_fn: (u8*) -> u8*(parameter) drop_fn: (u8*) -> void(parameter) data: u8*static Waker::new_nonowning(wake_fn: (u8*) -> void, data: u8*) -> WakerBuild 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).
Waker::wake(&this) -> voidRequest that the associated task be polled again.
Waker::wake_by_ref(&this) -> voidWake 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.
Waker::clone(&this) -> WakerDuplicate 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.
static Waker::take(slot: Waker*) -> WakerMove 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.
(parameter) slot: Waker*static Waker::replace(slot: Waker*, w: Waker) -> WakerStore w in slot and hand back the waker that was there.
(parameter) w: Wakerimport a::b;
import a::b::{ X, Y };
import a::b as c;
import a::b::*;Brings a module, or selected items from it, into scope. One path per declaration: use the brace form for several items, as to alias, and * for everything public (prefer the brace form; wildcards invite name collisions).
namespace std::future;std::future: stackless async foundations — Future, Poll, Context, Waker, and the drivers that poll them.
Context.waker: Wakerstatic Waker::new(wake_fn: (u8*) -> void, clone_fn: (u8*) -> u8*, drop_fn: (u8*) -> void, data: u8*) -> WakerBuild 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.
Waker::clone_fn: (u8*) -> u8*Waker::drop_fn: (u8*) -> voidPoll::Pendingfunction spawn<C, T>(ctx: C, body: (C) -> T) -> JoinHandle<T>
where C: Send, T: SendSpawn a thread that runs body(ctx) and returns a handle to its T result. ctx is moved into the new thread. body must be a function pointer or non-capturing lambda. Panics on allocation or pthread_create failure; use try_spawn for a fallible spawn.
Waker::clone(&this) -> WakerDuplicate 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.
static Waker::new_nonowning(wake_fn: (u8*) -> void, data: u8*) -> WakerBuild 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 Waker::take(slot: Waker*) -> WakerMove 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 Waker::replace(slot: Waker*, w: Waker) -> WakerStore w in slot and hand back the waker that was there.
static Waker::noop() -> WakerA waker that does nothing when woken. Used by drivers (like block_on) that re-poll unconditionally and never park a task.
Waker.data: u8*Waker::wake_fn: (u8*) -> voidnew T { field: value }
new E::Variant(args)
new T[n]Heap allocation. new T { .. } places a struct literal on the heap and yields a T*, and new E::V(args) does the same for an enum variant; new T[n] reserves n uninitialised T - the typed malloc. The storage comes from T's Allocate implementation, or else the global allocator. Parentheses after a struct's name are refused (E0117): there are no constructors, and a struct's static new(..) is an ordinary method.
Waker::wake_by_ref(&this) -> voidWake 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.
type trait Copy {}Types whose values can be duplicated by a bitwise copy. Integers, floats, pointers, and pure-POD structs qualify; anything that owns resources (heap storage, file handles, refcount) does not.
std::core::markerimplement struct Name { ... }
implement trait Trait for Type { ... }
implement u64 { ... }Adds methods to a type outside its declaration. implement struct T (or enum, or a bare primitive) opens an inherent block; implement trait Tr for T supplies a trait's methods for one type. Resolution is at compile time - no dynamic dispatch.
implement trait Trait for Type { ... }Introduces a trait implementation: the block supplies, for one concrete type, the method bodies the trait requires.
language referenceimplement trait Trait for Type { ... }Names the type a trait implementation is for. The block that follows supplies the bodies the trait requires.
language reference