Async Internals
This page explains how BoltFFI bridges Rust futures to target language async systems. You don’t need to understand this to use async functions, but it helps when debugging or optimizing async code.
The Polling Model
BoltFFI wraps each Rust future in a RustFuture<T> that exposes a C-compatible interface. The generated bindings use this interface to drive the future to completion. When you call an async function, the bindings create a future handle, poll it until ready, extract the result, and free the handle. The target language’s async runtime controls when polling happens, and BoltFFI uses continuation callbacks to signal when the future needs attention.
Generated FFI Functions
For each async function, BoltFFI generates five FFI functions:
- entry - Creates the
RustFutureand returns a handle - poll - Polls the future with a continuation callback
- complete - Extracts the result once the future is ready
- cancel - Marks the future as cancelled
- free - Deallocates the future
The bindings call these in sequence: entry to create, poll in a loop until ready, complete to get the result, and free to clean up.
Continuation Callbacks
When the bindings call poll, they pass a continuation callback and a handle. If the future is not ready, BoltFFI stores this callback. When the future wakes (I/O completes, timer fires, etc.), BoltFFI invokes the stored callback, which tells the bindings to poll again. This avoids busy-waiting and lets the target language’s async runtime manage scheduling.
Lock-Free Implementation
The polling mechanism uses atomic operations for state management. A scheduler tracks whether a continuation is stored, whether the future has been waked, and whether it’s been cancelled. State transitions use compare-and-swap operations, so multiple threads can interact with the future without locks.
Cancellation
When the target language cancels an async operation, the bindings call the cancel function. This marks the future as cancelled and immediately invokes any stored continuation with a ready signal. The next call to complete will return a cancellation status. The Rust future itself is not forcibly aborted - cancellation is cooperative.