-
Notifications
You must be signed in to change notification settings - Fork 3
kithara ring
Contract reviewed from PR #428, source revision 8fc1af7cf. This records that branch contract, not merged release status or new runtime validation. API and usage · All crates.
This crate owns one mechanism: a lock-free single-producer single-consumer
ring whose slots live in memory someone else owns. It implements
ringbuf::Storage for OwnedSlice<B>, where B is any owner that
dereferences mutably to [T] with T: Copy, and split turns such an owner
into the producer and consumer halves of an ordinary ringbuf::SharedRb.
The crate knows nothing about pools, budgets, or audio. kithara-bufpool
extends it with PoolRegion::ring, which hands it a pooled buffer; any other
owner of a contiguous slice works the same way. Push and pop are unchanged
ringbuf code, so the ring behaves exactly like a heap-backed one apart from
where its slots come from.
All unsafe code for storage over a foreign owner is confined here and runs
under Miri (just test miri); crates that use the ring, including
kithara-bufpool, keep forbid(unsafe_code).
-
splitmoves the owner behind its own allocation and takes the slot pointer and length once. The owner is not touched again until the storage drops, so the pointer stays valid whether the slice is inline in the owner or on the heap. That allocation is oneBoxof the owner's size per ring, made at creation and never on the push/pop path. - The ring's capacity is the slice length. Every slot starts vacant: values already in the owner's slice are never observed, only overwritten.
- The owner drops exactly once, after both halves are gone. Its own drop logic releases the memory; for a pooled buffer that returns it to the pool, so a consumer that outlives its producer keeps the budget charged until it drops.
- An empty slice cannot hold a ring.
splitreturns the unchanged owner as the error, andPoolRegion::ringmaps that toPoolError::EmptyRing.
T: Copy is required, not incidental. ringbuf treats slots as uninitialised
and drops popped values itself, while the owner also believes it holds
initialised values; a type with drop glue would be dropped twice. Copy
removes drop glue, so the two views never disagree.
Send and Sync hold when the owner is Send and T is Send: only the
slots are shared, and the single-producer single-consumer protocol keeps the
halves on disjoint ranges.