Skip to main content

PollFn

Type Alias PollFn 

Source
pub type PollFn = unsafe extern "C-unwind" fn(state: *mut u8, task_ctx: *mut u8) -> i64;
Expand description

The signature every compiled async fn’s poll function has – both the hand-written ones this module’s tests drive it with, and the ones async_lower.rs (Task 5) generates. Reads and writes state’s slots (see STATE_SLOT_TAG and friends) and reports POLL_PENDING or POLL_READY.

task_ctx is unused in this phase, and every call site in this module passes null. The parameter exists now, rather than being added later, because a future phase (channels, timers) needs a task to be able to park against an external event instead of being busy-repolled, and adding a parameter afterward would mean changing every already-compiled poll function’s signature.

"C-unwind", not plain "C": a panic cannot cross a plain "C" function’s boundary at all – it aborts the whole process on the spot, regardless of the workspace’s unwind panic strategy. Some of this module’s diagnostics are panics that a caller is meant to be able to observe – nova_rt_task_take_output’s take-once check, and [poll_one]’s rejection of a poll status the ABI does not define – and each has to leave the #[no_mangle] entry point it starts under. Declaring the ABI "C-unwind" permits that, and every entry point here (this indirect call included) shares it so this module has one ABI rather than two. It changes nothing else: "C-unwind" was stabilized in Rust 1.71 (under this workspace’s 1.78 MSRV) and marshals parameters and return values identically to "C", so a generated call site is byte-identical either way.

Constraint on generated poll functions: a panic must not cross their boundary. "C-unwind" says an unwind may pass through without aborting; it does not make a frame able to survive one. A poll function emitted by Cranelift or LLVM has no landing pads and no drop glue, so an unwind through it would skip whatever cleanup its frame ought to do and leave the executor’s QUEUE/TASKS describing a task that is neither running nor finished. Anything in a generated poll function that could panic must therefore either be provably unable to (nova_rt_check_bounds and nova_rt_panic_str both abort, not unwind) or catch it before returning. Every diagnostic in this module that a well-formed compiled Nova program can reach therefore goes through [abort_with] instead of panicking; the panics named above are reachable only from a Rust caller or from a compiler bug (see each one’s own doc comment). The permission this ABI grants exists for the Rust-side entry points below, not for compiled Nova frames.