Skip to main content

Consumer

Struct Consumer 

Source
pub struct Consumer<T: AnyBitPattern, const CAPACITY: usize, AllocT: Allocation<Slot<T>>> { /* private fields */ }
Available on non-crate feature tests_loom only.
Expand description

A reading handle of an SPMC broadcast queue.

Each consumer has its own private read cursor: every consumer observes every value the producer publishes, independently, unless it falls behind by more than CAPACITY slots.

Consumer is Send but not Sync: at most one thread may call try_read on a given consumer at a time. To get more consumers, request more at construction via new.

Implementations§

Source§

impl<T, const CAPACITY: usize, AllocT> Consumer<T, CAPACITY, AllocT>
where T: AnyBitPattern, AllocT: Allocation<Slot<T>>,

Source

pub fn try_read(&mut self) -> ReadResult<T>

Attempts to read the next value.

Wait-free in the common case (value available, or queue empty); lock-free when the producer is actively writing the target slot (the consumer spin-loops until the producer publishes).

§Protocol

Each slot carries an even/odd seq number: even = stable, odd = mid write. The consumer:

  1. Loads the slot’s seq. If odd, spin until it goes even.
  2. If the even seq is not the one expected for the current read cursor, the producer has lapped us; reload the write cursor, jump to the most recent slot, and return ReadResult::Lapped.
  3. Otherwise read the slot’s data, then re-load the seq. If the seq is unchanged the read is committed and a ReadResult::Value is returned; if the seq has moved, the read was torn and the loop retries.
§Examples
use low_latency_data_structures::spmc::{self, ReadResult, new};
use low_latency_data_structures::mem::global::GlobalAllocator;

let (producer, [mut consumer]) = new::<u64, 16, 1, GlobalAllocator>(
    spmc::Options::global_mlocked(),
);
assert_eq!(consumer.try_read(), ReadResult::Empty);
producer.publish(7);
assert_eq!(consumer.try_read(), ReadResult::Value(7));

Trait Implementations§

Source§

impl<T: AnyBitPattern, const CAPACITY: usize, AllocT: Allocation<Slot<T>>> Debug for Consumer<T, CAPACITY, AllocT>

Source§

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

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

impl<T: AnyBitPattern, const CAPACITY: usize, AllocT: Allocation<Slot<T>>> Send for Consumer<T, CAPACITY, AllocT>

Auto Trait Implementations§

§

impl<T, const CAPACITY: usize, AllocT> !Sync for Consumer<T, CAPACITY, AllocT>

§

impl<T, const CAPACITY: usize, AllocT> Freeze for Consumer<T, CAPACITY, AllocT>

§

impl<T, const CAPACITY: usize, AllocT> RefUnwindSafe for Consumer<T, CAPACITY, AllocT>
where AllocT: RefUnwindSafe, T: RefUnwindSafe,

§

impl<T, const CAPACITY: usize, AllocT> Unpin for Consumer<T, CAPACITY, AllocT>

§

impl<T, const CAPACITY: usize, AllocT> UnsafeUnpin for Consumer<T, CAPACITY, AllocT>

§

impl<T, const CAPACITY: usize, AllocT> UnwindSafe for Consumer<T, CAPACITY, AllocT>
where AllocT: RefUnwindSafe, T: RefUnwindSafe,

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> 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, 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, 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.