mini_io_queue/
lib.rs

1//! Fixed-length, allocation and lock-free, async I/O oriented single-producer single-consumer
2//! (SPSC) queues.
3//!
4//! # Overview
5//! This library provides several fixed-length queues for different use-cases, based around the same
6//! core:
7//!  - [`asyncio`] is a generic async, thread-safe, lock-free queue using [futures]. Read
8//!    operations can pause until data is available, and write operations can pause until space is
9//!    returned. The queue can act as an efficient I/O buffer with [`futures::AsyncRead`] and
10//!    [`futures::AsyncWrite`] implementations.
11//!  - [`blocking`] is a generic thread-safe queue. Read operations can block until data is
12//!    available, and write operations can block until space is returned. The queue can act as an
13//!    efficient I/O buffer with [`io::Read`] and [`io::Write`] implementations.
14//!  - [`nonblocking`] is a generic thread-safe, lock-free queue that is guaranteed to not block.
15//!    It can act as an efficient I/O buffer when read and write speed is matched or no locks
16//!    are available.
17//!
18//! All queues have separate `Reader` and `Writer` ends which can be sent across threads. Queues are
19//! designed with bulk operations in mind, so can safely be used with large read and write
20//! operations, such as in a byte array I/O context.
21//!
22//! The library also provides [`Ring`], a low-level atomic ring buffer building block used to
23//! implement the various queues available.
24//!
25//! The library supports `no_std` with a reduced feature set, and is highly configurable. With the
26//! default feature set, it does not require any dependencies.
27//!
28//! # Features
29//!
30//!  - `asyncio` - enables the [`asyncio`] queue, using the [`futures`] library. Requires [`alloc`].
31//!  - `blocking` - enables the [`blocking`] queue. Requires [`std`] (as this queue uses locks).
32//!  - `nonblocking` - enables the [`nonblocking`] queue. Requires [`alloc`].
33//!  - `heap-buffer` - enables [`HeapBuffer`], which allocates queue storage on the heap. Requires [`alloc`].
34//!  - `stack-buffer` - enables [`StackBuffer`], which allocates queue storage on the stack.
35//!  - `std-io` - enables implementations for standard I/O traits ([`io::Read`], [`io::Write`], and
36//!    [`futures::AsyncRead`] and [`futures::AsyncWrite`]). Requires [`std`].
37//!
38//! # Examples
39//! ## Simple async example
40//! ```
41//! use futures::executor::block_on;
42//! use futures::join;
43//! use mini_io_queue::asyncio::queue;
44//!
45//! let (mut reader, mut writer) = queue(8);
46//!
47//! let write_loop = async {
48//!     for i in 0..16 {
49//!         writer.write_all(&[i]).await.unwrap();
50//!     }
51//! };
52//!
53//! let read_loop = async {
54//!     for i in 0..16 {
55//!         let mut buf = [0];
56//!         reader.read_exact(&mut buf).await.unwrap();
57//!
58//!         assert_eq!(buf[0], i);
59//!     }
60//! };
61//!
62//! block_on(async { join!(write_loop, read_loop) });
63//! ```
64//!
65//! ## Blocking queue with a custom ring
66//! ```
67//! use mini_io_queue::blocking::queue_from_parts;
68//! use mini_io_queue::Ring;
69//! use mini_io_queue::storage::{HeapBuffer, Storage};
70//!
71//! // Create a queue with half of the underlying buffer in the read side.
72//! let ring = Ring::new(10);
73//! ring.advance_right(5);
74//!
75//! let mut buffer = HeapBuffer::new(10);
76//! buffer.slice_mut(0..5).copy_from_slice(&[1, 2, 3, 4, 5]);
77//!
78//! let (mut reader, _) = queue_from_parts(ring, buffer);
79//!
80//! for i in 1..=5 {
81//!     let mut buf = [0];
82//!     reader.read_exact(&mut buf).unwrap();
83//!
84//!     assert_eq!(buf[0], i);
85//! }
86//! ```
87//!
88//! [`io::Read`]: std::io::Read
89//! [`io::Write`]: std::io::Write
90//! [`HeapBuffer`]: storage::HeapBuffer
91//! [`StackBuffer`]: storage::StackBuffer
92
93#![cfg_attr(not(any(feature = "std")), no_std)]
94#![cfg_attr(docsrs, feature(doc_cfg))]
95#![deny(missing_docs, missing_debug_implementations)]
96#![deny(rustdoc::broken_intra_doc_links)]
97#![deny(rustdoc::private_intra_doc_links)]
98
99extern crate core;
100
101#[cfg(feature = "alloc")]
102extern crate alloc;
103
104mod cache_padded;
105mod region;
106mod ring;
107pub mod storage;
108
109#[cfg(feature = "asyncio")]
110#[cfg_attr(docsrs, doc(cfg(feature = "asyncio")))]
111pub mod asyncio;
112
113#[cfg(feature = "nonblocking")]
114#[cfg_attr(docsrs, doc(cfg(feature = "nonblocking")))]
115pub mod nonblocking;
116
117#[cfg(feature = "blocking")]
118#[cfg_attr(docsrs, doc(cfg(feature = "blocking")))]
119pub mod blocking;
120
121pub use self::region::*;
122pub use self::ring::*;