Struct rtrb::Consumer [−][src]
pub struct Consumer<T> { /* fields omitted */ }
Expand description
The consumer side of a RingBuffer
.
Can be moved between threads,
but references from different threads are not allowed
(i.e. it is Send
but not Sync
).
Can only be created with RingBuffer::split()
(together with its counterpart, the Producer
).
When the Consumer
is dropped, Producer::is_abandoned()
will return true
.
This can be used as a crude way to communicate to the sending thread
that no more data will be consumed.
When the Consumer
is dropped after the Producer
has already been dropped,
RingBuffer::drop()
will be called, freeing the allocated memory.
Examples
use rtrb::RingBuffer; let (producer, consumer) = RingBuffer::<f32>::new(1000).split();
Implementations
Attempts to pop an element from the queue.
The element is moved out of the ring buffer and its slot
is made available to be filled by the Producer
again.
If the queue is empty, an error is returned.
Examples
use rtrb::{PopError, RingBuffer}; let (mut p, mut c) = RingBuffer::new(1).split(); assert_eq!(p.push(10), Ok(())); assert_eq!(c.pop(), Ok(10)); assert_eq!(c.pop(), Err(PopError::Empty));
To obtain an Option<T>
, use .ok()
on the result.
assert_eq!(p.push(20), Ok(())); assert_eq!(c.pop().ok(), Some(20));
Attempts to read an element from the queue without removing it.
If the queue is empty, an error is returned.
Examples
use rtrb::{PeekError, RingBuffer}; let (mut p, c) = RingBuffer::new(1).split(); assert_eq!(c.peek(), Err(PeekError::Empty)); assert_eq!(p.push(10), Ok(())); assert_eq!(c.peek(), Ok(&10)); assert_eq!(c.peek(), Ok(&10));
Returns n
slots for reading.
If not enough slots are available, an error (containing the number of available slots) is returned.
The elements can be accessed with ReadChunk::as_slices()
or
by iterating over (a &mut
to) the ReadChunk
.
The provided slots are not automatically made available
to be written again by the Producer
.
This has to be explicitly done by calling ReadChunk::commit()
,
ReadChunk::commit_iterated()
or ReadChunk::commit_all()
.
You can “peek” at the contained values by simply
not calling any of the “commit” methods.
Examples
Items are dropped when ReadChunk::commit()
, ReadChunk::commit_iterated()
or ReadChunk::commit_all()
is called
(which is only relevant if T
implements Drop
).
use rtrb::RingBuffer; // Static variable to count all drop() invocations static mut DROP_COUNT: i32 = 0; #[derive(Debug)] struct Thing; impl Drop for Thing { fn drop(&mut self) { unsafe { DROP_COUNT += 1; } } } // Scope to limit lifetime of ring buffer { let (mut p, mut c) = RingBuffer::new(2).split(); assert!(p.push(Thing).is_ok()); // 1 assert!(p.push(Thing).is_ok()); // 2 if let Ok(thing) = c.pop() { // "thing" has been *moved* out of the queue but not yet dropped assert_eq!(unsafe { DROP_COUNT }, 0); } else { unreachable!(); } // First Thing has been dropped when "thing" went out of scope: assert_eq!(unsafe { DROP_COUNT }, 1); assert!(p.push(Thing).is_ok()); // 3 if let Ok(chunk) = c.read_chunk(2) { assert_eq!(chunk.len(), 2); assert_eq!(unsafe { DROP_COUNT }, 1); chunk.commit(1); // Drops only one of the two Things assert_eq!(unsafe { DROP_COUNT }, 2); } else { unreachable!(); } // The last Thing is still in the queue ... assert_eq!(unsafe { DROP_COUNT }, 2); } // ... and it is dropped when the ring buffer goes out of scope: assert_eq!(unsafe { DROP_COUNT }, 3);
See the crate-level documentation for more examples.
Returns the number of slots available for reading.
Since items can be concurrently produced on another thread, the actual number
of available slots may increase at any time (up to the RingBuffer::capacity()
).
To check for a single available slot,
using Consumer::is_empty()
is often quicker
(because it might not have to check an atomic variable).
Examples
use rtrb::RingBuffer; let (p, c) = RingBuffer::<f32>::new(1024).split(); assert_eq!(c.slots(), 0);
Returns true
if there are currently no slots available for reading.
Examples
use rtrb::RingBuffer; let (p, c) = RingBuffer::<f32>::new(1).split(); assert!(c.is_empty());
Since items can be concurrently produced on another thread, the ring buffer might not be empty for long:
if c.is_empty() { // The buffer might be empty, but it might as well not be // if an item was just produced on another thread. }
However, if it’s not empty, another thread cannot change that:
if !c.is_empty() { // At least one slot is guaranteed to be available for reading. }
Returns true
if the corresponding Producer
has been destroyed.
Examples
use rtrb::RingBuffer; let (mut p, mut c) = RingBuffer::new(7).split(); assert!(!c.is_abandoned()); assert_eq!(p.push(10), Ok(())); drop(p); assert!(c.is_abandoned()); // The items that are left in the ring buffer can still be consumed: assert_eq!(c.pop(), Ok(10));
Since the producer can be concurrently dropped on another thread, the consumer might become abandoned at any time:
if !c.is_abandoned() { // Right now, the producer might still be alive, but it might as well not be // if another thread has just dropped it. }
However, if it already is abandoned, it will stay that way:
if c.is_abandoned() { // The producer does definitely not exist anymore. }
Returns a read-only reference to the ring buffer.
Trait Implementations
Pull some bytes from this source into the specified buffer, returning how many bytes were read. Read more
Like read
, except that it reads into a slice of buffers. Read more
can_vector
)Determines if this Read
er has an efficient read_vectored
implementation. Read more
read_initializer
)Determines if this Read
er can work with buffers of uninitialized
memory. Read more
Read all bytes until EOF in this source, placing them into buf
. Read more
Read all bytes until EOF in this source, appending them to buf
. Read more
Read the exact number of bytes required to fill buf
. Read more
Creates a “by reference” adaptor for this instance of Read
. Read more
Creates an adaptor which will chain this stream with another. Read more
Auto Trait Implementations
impl<T> !RefUnwindSafe for Consumer<T>
impl<T> UnwindSafe for Consumer<T> where
T: RefUnwindSafe,