Expand description
§setback: setjmp/longjmp failure recovery, confined to C
protect runs a closure and returns Ok(value) on normal completion, or
Err(RecoveryError) if a longjmp - triggered by a stack-overflow fault
handler, an out-of-memory handler, or explicit user code via recover -
abandons the closure’s stack. Everything on the abandoned stack is leaked: no
Drop runs. See protect for the full safety contract.
§How it works
All setjmp/longjmp lives in a tiny C file (setback.c): rustc does not support
setjmp/longjmp, so calling setjmp from Rust risks miscompilation. Rust hands
C a data pointer and an extern "C" trampoline, C arms the mark and calls the
trampoline, which runs the closure. A longjmp resets the stack pointer to
that setjmp, jumping over every live Rust frame above it - the trampoline, the
closure, and its whole call tree - and abandons them where they sit. The jump
stops at the C frame, and protect returns Err(RecoveryError).
An uncaught panic crossing the extern "C" trampoline aborts (Rust 1.81+)
rather than entering C.
§One global registry, keyed by thread id
The crate owns a single static intrusive doubly-linked list of active marks.
Each protect call links one node, tagged with the caller’s ThreadId, and
unlinks it on exit. One shared fault handler, given the faulting thread’s id,
calls recover to find that thread’s innermost active mark and jump into it,
or can_recover to ask whether such a mark exists without jumping.
The link/unlink runs inside a critical_section, the protected closure runs
outside it. You supply the critical-section impl in the final binary.
Structs§
- Assert
Unwind Safe - Wrap a capture (or a whole closure) to assert it is unwind-safe if needed,
satisfying the
UnwindSafebound onprotect. Safe in itself, you should still fulfill the safety contract ofprotectwhen the closure runs. A simple wrapper around a type to assert that it is unwind safe. - Recovery
Error - Returned by
protectwhen the closure’s stack was abandoned by alongjmp. - Recovery
Failure - Returned by
recoverwhen the giventidhas no activeprotectscope.
Constants§
- RECOVERY_
GAP_ BYTES - Bytes of stack that
protectreserves below the recovery mark before it runs the closure - the gap a fault handler may rely on when choosing where to runrecover. See the “Recovery-stack guarantee” onprotect.
Functions§
- can_
recover - Whether
recoverwould find a scope:truewhentidhas an activeprotectscope that acceptscause. - protect⚠
- Run
funder recovery protection, tagging this scope withtid. Catches any cause; seeprotect_causeto recover from a single cause only. - protect_
cause ⚠ - Like
protect, but only recovers whenrecover’scauseequalscause; any other cause skips this scope. Seeprotectfor the full contract. - recover⚠
- From the shared fault/OOM handler: recover the thread identified by
tidby jumping into its innermost active scope that acceptscause, reporting it.protectscopes accept any cause;protect_causescopes accept one.
Type Aliases§
- Thread
Id - Identifier the caller uses to tag a
protectscope and that the fault handler uses to find it again. Cast your RTOS task handle / index tousize.