# `unbounded_spsc`
> An "unbounded" extension of `bounded_spsc_queue`.
This crate provides an unbounded SPSC queue with asynchronous sends, using
[`bounded_spsc_queue`](https://crates.io/crates/bounded-spsc-queue) for the
internal queue. This provides better performance and cache coherence than the
linked-list queue used in the standard `std::sync::mpsc::channel`.
Besides being bounded, `bounded_spsc_queue` itself only provides spin-wait for
blocking `recv` (blocking when buffer is empty), so the blocking-wait code
found in the standard library is adapted here to provide a more CPU-friendly
blocking mechanism, both with and without timeout. This code is essentially
lock-free; there are no mutexes or condvars involved.
Note that `bounded_spsc_queue` does not support zero-size message types (such
as unit type `()`), and will crash with an unspecified error; here we check for
zero-size and `panic!` with an error message.
Sends are always asynchronous; if the underlying buffer is full, a new buffer
is created that is twice the size of the previous buffer, and sent to the
consumer by means of a standard asynchronous `mpsc` channel. Currently there
are no mechanisms for specifying initial capacity (hard-coded to 128) or
shrinking.
Synchronous send (blocking when buffer is full) is not provided here: for that
use either `bounded_spsc_queue` directly (spin-wait) or a standard
`std::sync::mpsc::sync_channel` (block-waiting; uses a vector-backed buffer
internally).
Also taken from the standard library is the (unstable) implementation of the
`select!` macro and related functionality that allows waiting on multiple
receivers. As noted in the original implementation, this code is sub-optimal
since it involves some allocations, and does not implement any kind of
"fairness" protocol-- see <https://github.com/rust-lang/rust/issues/27800>.