1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
//! Magnetic contains a set of high-performance queues useful for developing
//! low-latency applications. All queues are FIFO unless otherwise specified.
//!
//! # Examples
//!
//! ```
//! use std::thread::spawn;
//! use magnetic::spsc::spsc_queue;
//! use magnetic::buffer::dynamic::DynamicBuffer;
//! use magnetic::{Producer, Consumer};
//!
//! let (p, c) = spsc_queue(DynamicBuffer::new(32).unwrap());
//!
//! // Push and pop within a single thread
//! p.push(1).unwrap();
//! assert_eq!(c.pop(), Ok(1));
//!
//! // Push and pop from multiple threads. Since this example is using the
//! // SPSC queue, only one producer and one consumer are allowed.
//! let t1 = spawn(move || {
//! for i in 0..10 {
//! println!("Producing {}", i);
//! p.push(i).unwrap();
//! }
//! p
//! });
//!
//! let t2 = spawn(move || {
//! loop {
//! let i = c.pop().unwrap();
//! println!("Consumed {}", i);
//! if i == 9 { break; }
//! }
//! });
//!
//! t1.join().unwrap();
//! t2.join().unwrap();
//! ```
#![deny(missing_docs)]
pub mod buffer;
pub mod mpmc;
pub mod mpsc;
pub mod spmc;
pub mod spsc;
mod util;
/// Possible errors for `Producer::push`
#[derive(Debug, PartialEq)]
pub enum PushError<T> {
/// Consumer was destroyed
Disconnected(T),
}
/// Possible errors for `Producer::try_push`
#[derive(Debug, PartialEq)]
pub enum TryPushError<T> {
/// Queue was full
Full(T),
/// Consumer was destroyed
Disconnected(T),
}
/// Possible errors for `Consumer::pop`
#[derive(Debug, PartialEq)]
pub enum PopError {
/// Producer was destroyed
Disconnected,
}
/// Possible errors for `Consumer::try_pop`
#[derive(Debug, PartialEq)]
pub enum TryPopError {
/// Queue was empty
Empty,
/// Producer was destroyed
Disconnected,
}
/// The consumer end of the queue allows for sending data. `Producer<T>` is
/// always `Send`, but is only `Sync` for multi-producer (MPSC, MPMC) queues.
pub trait Producer<T> {
/// Add value to front of the queue. This method will block if the queue
/// is currently full.
fn push(&self, value: T) -> Result<(), PushError<T>>;
/// Attempt to add a value to the front of the queue. If the value was
/// added successfully, `None` will be returned. If unsuccessful, `value`
/// will be returned. An unsuccessful push indicates that the queue was
/// full.
fn try_push(&self, value: T) -> Result<(), TryPushError<T>>;
}
/// The consumer end of the queue allows for receiving data. `Consumer<T>` is
/// always `Send`, but is only `Sync` for multi-consumer (SPMC, MPMC) queues.
pub trait Consumer<T> {
/// Remove value from the end of the queue. This method will block if the
/// queue is currently empty.
fn pop(&self) -> Result<T, PopError>;
/// Attempt to remove a value from the end of the queue. If the value was
/// removed successfully, `Some(T)` will be returned. If unsuccessful,
/// `None` will be returned. An unsuccessful pop indicates that the queue
/// was empty.
fn try_pop(&self) -> Result<T, TryPopError>;
}