traits
import std::future::traits; · source
Types
Future
type trait Future {
type Output;
poll(mut &this, cx: Context*) -> Poll<This::Output>;
}
The one trait the whole async machinery is defined against. poll is called with a Context carrying the task's Waker; it returns Poll::Pending after arranging to be woken, or Poll::Ready(v) once. Output is an associated type, and implement Future<T> for X is the positional sugar for binding it, exactly as with Iterator.
An async function produces a compiler-generated type that implements this trait; you implement it by hand only for a leaf future — one that talks to the reactor or the blocking pool directly. The contract a leaf must honour:
- Attempt, then register. Try the operation first; only on "would block" register the waker and return
Pending. The reactor arms level-triggered, so readiness that arrived between the two is still reported. - Own what you touch. A future is moved between polls, so it cannot hold a raw pointer into the caller's frame across a suspension. The socket futures in
nettake the handle and buffer by value and hand them back in their output for this reason. - Release on drop. A parked future's
Dropmust cancel its registration, because that drop is the only cancellation there is. - Do not poll after
Ready. The library futures panic if you do; a completed future has already moved its output out.
Associated types
| Type |
|---|
Output |
Methods
poll(mut &this, cx: Context*) -> Poll<This::Output>;
Implementors
implement<A, B, OA, OB> trait Future<(OA, OB)> for struct Join<A, B, OA, OB> where A: Future<OA>, B: Future<OB>
std::future::combinator
implement<A, B, T1, T2, E> trait Future<Result<(T1, T2), E>> for struct TryJoin<A, B, T1, T2, E> where A: Future<Result<T1, E>>, B: Future<Result<T2, E>>
std::future::combinator
implement<A, B, OA, OB> trait Future<Selected<OA, OB>> for struct Select<A, B, OA, OB> where A: Future<OA>, B: Future<OB>
std::future::combinator
implement<F, O> trait Future<Result<O, Elapsed>> for struct Timeout<F, O> where F: Future<O>
std::future::combinator
implement<T> trait Future<T> for struct Ready<T>
std::future::ready
implement<T> trait Future<T> for struct PendingThenReady<T>
std::future::ready
implement trait Future for struct Sleep
std::future::timer
implement trait Future for struct Resolve
std::net::dns
implement trait Future for struct TcpRead
std::net::socket::tcp
implement trait Future for struct TcpWrite
std::net::socket::tcp
implement trait Future for struct TcpAccept
std::net::socket::tcp
implement trait Future for struct TcpConnect
std::net::socket::tcp
implement trait Future for struct UdpSendTo
std::net::socket::udp
implement trait Future for struct UdpSend
std::net::socket::udp
implement trait Future for struct UdpRecvFrom
std::net::socket::udp
implement trait Future for struct UdpRecv
std::net::socket::udp
implement trait Future for struct TlsHandshake
std::net::tls::future
implement trait Future for struct TlsRead
std::net::tls::future
implement trait Future for struct TlsWrite
std::net::tls::future
implement trait Future for struct ChildWait
std::process::child
implement trait Future for struct PipeDrain
std::process::child
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 trait Name : Base {
method(&this, other: &This) -> Ret;
}Names a set of methods a type may implement. Inside the body This is the implementing type; methods may carry default bodies, and a trait may require a base trait (type trait Ord : Eq). Generic code asks for a trait with where T: Name.
type trait Future {
type Output;
poll(mut &this, cx: Context*) -> Poll<This::Output>;
}An asynchronous computation. poll drives it one step: Ready(v) when the value is available, Pending when it is not yet (the future has arranged, via cx's waker, to be polled again later).
type Item;
type Output = i64;An associated type on a trait: named in the trait body, filled in by each implementation, and referred to as This::Item or I::Item.
Future::type OutputFuture::poll(mut &this, cx: Context*) -> Poll<This::Output>mut &this
mut &TypeAn exclusive, mutating borrow. As a receiver, mut &this lets the method modify the fields - and callers can see that from the signature alone. As a parameter type, mut &T lets the callee mutate through the reference while the caller keeps ownership.
&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.
(parameter) cx: Context*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.
type enum Poll<T> {
Ready(T);
Pending;
}The result of polling a Future: either the final value, or a signal that the value is not ready yet and the task should be re-polled after its Waker fires.
ThisThe implementing type, inside a trait or implement body. other: &This in a trait method is a reference to whichever type implements it; This::Item names an associated type.
Future::type Outputimport 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.
Future::poll(mut &this, cx: Context*) -> Poll<This::Output>Poll::Ready(T)implement 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.
type trait Future {
type Output;
poll(mut &this, cx: Context*) -> Poll<This::Output>;
}An asynchronous computation. poll drives it one step: Ready(v) when the value is available, Pending when it is not yet (the future has arranged, via cx's waker, to be polled again later).
type parameter Timplement trait Trait for Type { ... }Names the type a trait implementation is for. The block that follows supplies the bodies the trait requires.
language referencetype trait Iterator {
type Item;
next(mut &this) -> Option<This::Item>;
count(mut &this) -> u64;
fold<Acc>(mut &this, initial: Acc, f: (Acc, This::Item) -> Acc) -> Acc;
for_each(mut &this, f: (This::Item) -> void) -> void;
take(this, n: u64) -> TakeIter<This>;
skip(this, n: u64) -> SkipIter<This>;
map<B>(this, f: (This::Item) -> B) -> MapIter<This, B>;
filter(this, pred: (&This::Item) -> boolean) -> FilterIter<This>;
chain<J>(this, other: J) -> ChainIter<This, J>;
// … 7 more
}async function name(param: Type) -> T { ... }Compiles the function into a stackless state machine. Calling it builds a future whose output is the declared return type; nothing runs until that future is polled. Allowed on free functions, methods, and trait methods.
language referencefunction name<T>(param: Type) -> Ret { ... }Declares a function. Parameters are written name: Type and are never inferred; the return type follows -> and defaults to void. Declaration order does not matter: every signature is collected before any body is checked, so functions may call each other freely and recurse.
Poll::Pendingtype struct Ready<T> {
value: Option<T>;
}A future that is already complete: the first poll returns Ready(value). The value is held in an Option and moved out on completion, so polling a Ready a second time is a contract violation (it panics) rather than a double-move.
type struct Output {
status: ExitStatus;
stdout: Array<u8>;
stderr: Array<u8>;
}type parameter Awhere A: Future
type parameter Bwhere B: Future
type parameter OAtype parameter OBtype 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 Join<A, B, OA, OB> {
a: A;
b: B;
a_out: Option<OA>;
b_out: Option<OB>;
a_done: boolean;
b_done: boolean;
}Runs two futures concurrently and completes with both results once both have finished. Each child is polled only until it completes; its value is parked in an Option until the other one catches up.
where T: Ord + Clone, U: HashConstrains generic parameters to types that implement the listed traits, which is what makes those traits' methods callable on T. Bounds on one parameter join with +; parameters separate with ,. A where on a single method narrows the type's parameter for that method only.
type parameter T1type parameter T2type parameter Etype struct TryJoin<A, B, T1, T2, E> {
a: A;
b: B;
a_out: Option<T1>;
b_out: Option<T2>;
a_done: boolean;
b_done: boolean;
done: boolean;
}Runs two fallible futures concurrently and completes with both values, or with the FIRST error either of them reports.
std::future::combinatortype enum Selected<L, R> {
First(L);
Second(R);
}Which side of a Select finished first.
type struct Select<A, B, OA, OB> {
a: A;
b: B;
done: boolean;
}Runs two futures concurrently and completes as soon as EITHER finishes, reporting which one it was. The loser is dropped with this future, which cancels it.
std::future::combinatortype parameter Fwhere F: Future
type parameter Otype struct Elapsed {
deadline: i64;
}A Timeout expired before the operation it was timing finished.
type struct Timeout<F, O> {
fut: F;
sleep: Sleep;
done: boolean;
}Runs a future with a deadline: Ok(value) if it finishes in time, otherwise Err(Elapsed).
type struct PendingThenReady<T> {
remaining: u32;
value: Option<T>;
}A future that reports Pending for its first pending_count polls and then completes with value. Exercises the suspend/resume path end-to-end under a driver without any I/O or threads — the canonical Phase-1 validation future.
implement trait Trait for Type { ... }Introduces a trait implementation: the block supplies, for one concrete type, the method bodies the trait requires.
language referencetype struct Sleep {
deadline: i64;
id: u64;
rt: Reactor*;
}A future that completes once the monotonic clock reaches its deadline.
std::future::timertype struct Resolve {
host: Str;
job: ResolveJob*;
}Resolve host without stalling the executor: the lookup runs on the BlockingPool's threads and the task parks until it answers.
type struct TcpRead {
stream: TcpStream;
buf: Array<u8>;
rt: Reactor*;
}Read as soon as the socket has anything to give. Completes with the byte count — 0 means the peer closed its end — or the error that ended it.
std::net::socket::tcptype struct TcpWrite {
stream: TcpStream;
buf: Array<u8>;
rt: Reactor*;
}Write as soon as the socket has room. Completes with the number of bytes accepted, which may be fewer than asked for — a caller with more to send starts another write for the remainder, which is why the buffer comes back untouched. Owns the socket and the buffer exactly as TcpRead does, and for the same reason.
type struct TcpAccept {
listener: TcpListener;
rt: Reactor*;
}Accept the next incoming connection. An accepted socket does not inherit the listener's non-blocking mode, so it is set here — it is about to be used with these same futures. Owns the listener for the duration and hands it back in the TcpAccepted, so a server loop starts the next accept from that.
type struct TcpConnect {
fd: i32;
addr: [u8;
28];
addrlen: u32;
err: IoError;
rt: Reactor*;
}Connect to a remote address without blocking. The socket is opened and the handshake started when the future is created; each poll asks the OS whether it finished, parking on writability in between. The socket is closed if the future is dropped before it completes.
std::net::socket::tcptype struct UdpSendTo {
socket: UdpSocket;
buf: Array<u8>;
dest: SocketAddr;
rt: Reactor*;
}Send one datagram to dest. Completes with the number of bytes the kernel accepted; a partial datagram is never sent, so that is the whole buffer on success. The buffer comes back untouched.
type struct UdpSend {
socket: UdpSocket;
buf: Array<u8>;
rt: Reactor*;
}Send one datagram on a connected socket. Fails NotConnected if no default peer was pinned. Owns the socket and the buffer exactly as UdpSendTo does.
type struct UdpRecvFrom {
socket: UdpSocket;
buf: Array<u8>;
rt: Reactor*;
}Receive one datagram, completing with the byte count and the peer that sent it. A datagram longer than the buffer is truncated (the tail is discarded - POSIX UDP semantics).
std::net::socket::udptype struct UdpRecv {
socket: UdpSocket;
buf: Array<u8>;
rt: Reactor*;
}Receive on a connected socket, dropping the peer address - it can only be the connected peer. Truncates an oversized datagram, as UdpRecvFrom does.
type struct TlsHandshake {
tls: TlsStream;
is_client: boolean;
verify: boolean;
rt: Reactor*;
armed: u32;
}Drive a TLS handshake to completion without blocking. SSL_connect (client) or SSL_accept (server) is re-issued on every poll — which is exactly what OpenSSL wants after a WANT_* — until it reports success or a real failure.
type struct TlsRead {
tls: TlsStream;
buf: Array<u8>;
rt: Reactor*;
armed: u32;
}Read decrypted bytes as soon as the connection has some. Completes with the byte count — 0 means the peer sent close_notify, the TLS equivalent of EOF — or the error that ended it.
type struct TlsWrite {
tls: TlsStream;
buf: Array<u8>;
rt: Reactor*;
armed: u32;
}Write plaintext as soon as the connection has room for the resulting record. Completes with the number of bytes accepted, which may be fewer than asked for — a caller with more to send starts another write for the remainder, which is why the buffer comes back untouched.
std::net::tls::futuretype struct ChildWait {
pid: i32;
handle: u64;
exit_fd: i32;
rt: Reactor*;
job: ChildWaitJob*;
routed: boolean;
}Wait for a child to exit without stalling the executor. The machinery behind Child::join; await that rather than driving this directly, because only the method updates the Child's bookkeeping.
type struct PipeDrain {
fd: i32;
buf: Array<u8>;
rt: Reactor*;
job: PipeDrainJob*;
routed: boolean;
on_reactor: boolean;
}Read one captured pipe to EOF without stalling the executor. The machinery behind Command::collect; await that rather than driving this directly.