Skip to main content

SpscQueue

Struct SpscQueue 

Source
pub struct SpscQueue<T> { /* private fields */ }
Expand description

A lock-free single-producer single-consumer bounded queue.

This queue is designed for high-performance inter-core communication. It uses atomic operations with Acquire/Release ordering to ensure correct synchronization without locks.

§Safety

This queue is only safe when there is exactly one producer thread and one consumer thread. Multiple producers or consumers will cause data races.

§Example

use laminar_core::tpc::SpscQueue;

let queue: SpscQueue<i32> = SpscQueue::new(1024);

// Producer
assert!(queue.push(42).is_ok());

// Consumer
assert_eq!(queue.pop(), Some(42));

Implementations§

Source§

impl<T> SpscQueue<T>

Source

pub fn new(capacity: usize) -> Self

Creates a new SPSC queue with the given capacity.

The capacity will be rounded up to the next power of 2 for efficiency.

§Panics

Panics if capacity is 0 or would overflow when rounded to power of 2.

Source

pub fn capacity(&self) -> usize

Returns the capacity of the queue.

Source

pub fn is_empty(&self) -> bool

Returns true if the queue is empty.

Note: This is a snapshot and may change immediately after returning.

Source

pub fn is_full(&self) -> bool

Returns true if the queue is full.

Note: This is a snapshot and may change immediately after returning.

Source

pub fn len(&self) -> usize

Returns the current number of items in the queue.

Note: This is a snapshot and may change immediately after returning.

Source

pub fn push(&self, item: T) -> Result<(), T>

Push an item to the queue.

Returns Ok(()) if successful, or Err(item) if the queue is full.

§Errors

Returns the item back if the queue is full.

§Safety

This method must only be called by the single producer thread.

Source

pub fn pop(&self) -> Option<T>

Pop an item from the queue.

Returns Some(item) if successful, or None if the queue is empty.

§Safety

This method must only be called by the single consumer thread.

Source

pub fn push_batch(&self, items: impl IntoIterator<Item = T>) -> usize

Push multiple items to the queue.

Returns the number of items successfully pushed. Items are pushed in order, stopping at the first failure.

§Safety

This method must only be called by the single producer thread.

Source

pub fn pop_batch(&self, max_count: usize) -> Vec<T>

Pop multiple items from the queue.

Returns a vector of up to max_count items.

§Safety

This method must only be called by the single consumer thread.

§Note

This method allocates memory. For zero-allocation polling, use pop_batch_into or pop_each instead.

Source

pub fn pop_batch_into(&self, buffer: &mut [MaybeUninit<T>]) -> usize

Pop multiple items into a caller-provided buffer (zero-allocation).

Items are written to buffer starting at index 0. Returns the number of items actually popped (0 if queue empty or buffer full).

§Safety

This method must only be called by the single consumer thread.

After this method returns n, the first n elements of buffer are initialized and can be safely read with assume_init_read().

§Example
use laminar_core::tpc::SpscQueue;
use std::mem::MaybeUninit;

let queue: SpscQueue<i32> = SpscQueue::new(16);
queue.push(1).unwrap();
queue.push(2).unwrap();

let mut buffer: [MaybeUninit<i32>; 8] = [MaybeUninit::uninit(); 8];
let count = queue.pop_batch_into(&mut buffer);

assert_eq!(count, 2);
// SAFETY: We just initialized these elements
unsafe {
    assert_eq!(buffer[0].assume_init(), 1);
    assert_eq!(buffer[1].assume_init(), 2);
}
Source

pub fn pop_each<F>(&self, max_count: usize, f: F) -> usize
where F: FnMut(T) -> bool,

Pop items and call a callback for each one (zero-allocation).

Processing stops when either:

  • max_count items have been processed
  • The queue becomes empty
  • The callback returns false

Returns the number of items processed.

§Safety

This method must only be called by the single consumer thread.

§Example
use laminar_core::tpc::SpscQueue;

let queue: SpscQueue<i32> = SpscQueue::new(16);
queue.push(1).unwrap();
queue.push(2).unwrap();
queue.push(3).unwrap();

let mut sum = 0;
let count = queue.pop_each(10, |item| {
    sum += item;
    true // Continue processing
});

assert_eq!(count, 3);
assert_eq!(sum, 6);
Source

pub fn peek(&self) -> Option<&T>

Peek at the next item without removing it.

Returns None if the queue is empty.

§Safety

This method must only be called by the single consumer thread.

Trait Implementations§

Source§

impl<T: Debug> Debug for SpscQueue<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Drop for SpscQueue<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<T: Send> Send for SpscQueue<T>

Source§

impl<T: Send> Sync for SpscQueue<T>

Auto Trait Implementations§

§

impl<T> !Freeze for SpscQueue<T>

§

impl<T> !RefUnwindSafe for SpscQueue<T>

§

impl<T> Unpin for SpscQueue<T>

§

impl<T> UnwindSafe for SpscQueue<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> ArchivePointee for T

Source§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
Source§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> LayoutRaw for T

Source§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Returns the layout of the type.
Source§

impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
where T: SharedNiching<N1, N2>, N1: Niching<T>, N2: Niching<T>,

Source§

unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool

Returns whether the given value has been niched. Read more
Source§

fn resolve_niched(out: Place<NichedOption<T, N1>>)

Writes data to out indicating that a T is niched.
Source§

impl<T> Pointee for T

Source§

type Metadata = ()

The metadata type for pointers and references to this type.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more