indexbus_blocking/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]
2#![deny(missing_docs)]
3
4//! Blocking (Tier B) adapters over `indexbus-core` using `indexbus-wake`.
5//!
6//! This crate keeps `indexbus-core` bytes-first and nonblocking, and provides optional
7//! **std-only** blocking wrappers that use the appended wake sections in the v1 ABI.
8//!
9//! # Feature requirements
10//!
11//! - This crate is **std-only** (`std` is the default and only meaningful feature).
12//! - Blocking semantics require layouts/mappings that include wake sections.
13//!
14//! # Contracts
15//!
16//! - Blocking operations park the current thread (directly or indirectly) until progress is
17//! possible, and are intended for Tier B integrations.
18//! - Wake-backed adapters must not busy-spin while idle; they rely on `indexbus-wake`.
19//! - On wake-capable mappings, blocking send/recv are expected to be fair with respect to
20//! other waiters.
21//!
22//! # Error semantics
23//!
24//! - Constructor helpers return `Error::MissingBlockingCapability` when wake sections are
25//! required but not present.
26//! - Layout validation failures from `indexbus-core` are propagated.
27//!
28//! # When wake sections are absent
29//!
30//! Blocking adapters require both:
31//! - `INDEXBUS_CAP_SUPPORTS_BLOCKING` in the layout header, and
32//! - an appended wake section at the next 64B boundary (as validated by `indexbus-core`).
33//!
34//! If either requirement is not met, constructors like `split_spsc_blocking` and
35//! `fanout_handles_blocking` return an error (`Error::MissingBlockingCapability` or a core layout
36//! validation error).
37//!
38//! **Fallback:** use the nonblocking handles from `indexbus-core` (and/or `indexbus-route`) and
39//! drive progress via a polling loop appropriate to your application (e.g. `route_once_with_stats`
40//! plus `std::thread::yield_now()`/sleep/backoff).
41//!
42//! ## Minimal usage (compile-only)
43//!
44//! Blocking adapters require a mapping that includes a v1 wake section. Transports like
45//! `indexbus-transport-shm` can create such regions.
46//!
47//! ```no_run
48//! use indexbus_abi::{caps, layouts::SharedLayout};
49//! use indexbus_blocking::split_spsc_blocking;
50//! use indexbus_core::init_shared_layout_with_layout_bytes;
51//!
52//! // SharedLayout is large; allocate it on the heap.
53//! let mut shared: Box<SharedLayout> = Box::new(unsafe { core::mem::zeroed() });
54//!
55//! // In a real mapping, `layout_bytes` must include the appended wake section bytes.
56//! init_shared_layout_with_layout_bytes(
57//! &mut shared,
58//! caps::INDEXBUS_CAP_SUPPORTS_EVENTS | caps::INDEXBUS_CAP_SUPPORTS_BLOCKING,
59//! core::mem::size_of::<SharedLayout>() as u32,
60//! );
61//!
62//! let _blocking = split_spsc_blocking(&mut shared);
63//! ```
64
65#[cfg(feature = "std")]
66extern crate std;
67
68#[cfg(feature = "std")]
69mod errors;
70#[cfg(feature = "std")]
71mod events;
72#[cfg(feature = "std")]
73mod fanout;
74#[cfg(feature = "std")]
75mod internal;
76
77#[cfg(feature = "std")]
78pub use errors::{Error, Result};
79#[cfg(feature = "std")]
80pub use events::{
81 split_mpsc_blocking, split_spsc_blocking, BlockingMpscConsumer, BlockingMpscProducer,
82 BlockingSpscReceiver, BlockingSpscSender,
83};
84
85#[cfg(feature = "std")]
86pub use fanout::{
87 fanout_handles_blocking, fanout_router_ref_blocking, BlockingFanoutConsumer,
88 BlockingFanoutProducer, BlockingFanoutRouter, BlockingFanoutRouterRef,
89};