futures-intrusive
Async/await synchronization primitives for Rust built on intrusive collections
Repository Health
Technical Analysis
futures-intrusive is a Rust crate that provides Futures-based and async/await compatible synchronization primitives and channels. It offers oneshot, MPMC, and state-broadcast channels alongside mutexes, semaphores, manual reset events, and a timer.
The crate is built around intrusive collections, where each waiting future stores its own list node instead of the container allocating one. This keeps the synchronization types compact, works in no-std environments, and avoids per-waiter heap allocations while remaining fully compatible with the standard Future and Waker model.
What You Get
- Async channels in oneshot, MPMC, and state-broadcast flavors
- Async Mutex and Semaphore primitives for coordinating task access
- A ManualResetEvent for signaling between async tasks
- A future-based timer for delays and timeouts
- no-std support with optional alloc and std feature gates
Common Use Cases
- Bounding concurrency with an async semaphore around a shared resource
- Passing values between async tasks over MPMC or oneshot channels
- Building embedded or no-std async applications that need synchronization
- Signaling readiness or completion across tasks with a reset event
Under The Hood
Architecture - The crate is organized around an intrusive doubly-linked list (intrusive_double_linked_list.rs) and pairing heap (intrusive_pairing_heap.rs) that store waiter nodes provided by the pinned futures themselves. Each primitive under src/sync (mutex.rs, semaphore.rs, manual_reset_event.rs) and src/channel (mpmc.rs, oneshot.rs, state_broadcast.rs) registers a future’s Waker into its intrusive queue on a pending poll and wakes and removes it when it becomes ready, so containers hold only a head pointer regardless of waiter count.
Tech Stack - Written in Rust (2018 edition) with a minimal dependency set: futures-core for the async traits, lock_api for the locking abstraction, and optional parking_lot behind the std feature. Feature flags (alloc, std, default) gate no-std versus std builds. Benchmarks use criterion and dev builds pull in tokio, async-std, and crossbeam for comparison.
Code Quality - Extensive integration tests live under tests/ covering every primitive (mutex, semaphore, mpmc_channel, oneshot_channel, state_broadcast_channel, manual_reset_event, timer), and benches/ provides criterion benchmarks. The unsafe pointer manipulation inherent to intrusive lists is isolated in the double-linked-list and pairing-heap modules, keeping the public primitives safe.
API Design - The public API mirrors familiar synchronization types (Mutex, Semaphore, channels) so it reads naturally to anyone who has used std or tokio equivalents, and rustdoc coverage plus runnable examples (cancellation.rs, philosophers.rs) lower the barrier. The main friction is understanding the no-std feature gating and the intrusive-collection constraints around pinning.