ringbuf_basedrop/lib.rs
1//! This is a fork of the [`ringbuf`] crate that uses [`basedrop`]'s `Shared` pointer in place of `Arc`. This ensures that when all references to the ring buffer are dropped, the underlying `Vec` will never potentially get deallocated (a non-realtime safe operation) in the realtime thread. Instead, all allocations are cleaned up in whatever thread owns the basedrop `Collector` object.
2//!
3//! This is especially useful for audio applications.
4//!
5//! [`ringbuf`]: https://github.com/agerasev/ringbuf
6//! [`basedrop`]: https://github.com/glowcoil/basedrop
7//!
8//! --------------------------------------------------------------
9//!
10//! Lock-free single-producer single-consumer (SPSC) FIFO ring buffer with direct access to inner data.
11//!
12//! # Overview
13//!
14//! `RingBuffer` is the initial structure representing ring buffer itself.
15//! Ring buffer can be splitted into pair of `Producer` and `Consumer`.
16//!
17//! `Producer` and `Consumer` are used to append/remove elements to/from the ring buffer accordingly. They can be safely sent between threads.
18//! Operations with `Producer` and `Consumer` are lock-free - they succeed or fail immediately without blocking or waiting.
19//!
20//! Elements can be effectively appended/removed one by one or many at once.
21//! Also data could be loaded/stored directly into/from [`Read`]/[`Write`] instances.
22//! And finally, there are `unsafe` methods allowing thread-safe direct access in place to the inner memory being appended/removed.
23//!
24//! [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
25//! [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
26//!
27//! When building with nightly toolchain it is possible to run benchmarks via `cargo bench --features benchmark`.
28//!
29//! # Examples
30//!
31//! ## Simple example
32//!
33//! ```rust
34//! # extern crate ringbuf_basedrop;
35//! use ringbuf_basedrop::RingBuffer;
36//! use basedrop::Collector;
37//! # fn main() {
38//! let collector = Collector::new();
39//!
40//! let rb = RingBuffer::<i32>::new(2);
41//! let (mut prod, mut cons) = rb.split(&collector.handle());
42//!
43//! prod.push(0).unwrap();
44//! prod.push(1).unwrap();
45//! assert_eq!(prod.push(2), Err(2));
46//!
47//! assert_eq!(cons.pop().unwrap(), 0);
48//!
49//! prod.push(2).unwrap();
50//!
51//! assert_eq!(cons.pop().unwrap(), 1);
52//! assert_eq!(cons.pop().unwrap(), 2);
53//! assert_eq!(cons.pop(), None);
54//! # }
55//! ```
56
57#![no_std]
58#![cfg_attr(feature = "benchmark", feature(test))]
59
60extern crate alloc;
61#[cfg(feature = "std")]
62extern crate std;
63
64#[cfg(feature = "benchmark")]
65extern crate test;
66
67#[cfg(feature = "benchmark")]
68mod benchmark;
69
70#[cfg(test)]
71mod tests;
72
73mod consumer;
74mod producer;
75mod ring_buffer;
76
77pub use consumer::*;
78pub use producer::*;
79pub use ring_buffer::*;