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

Formats the value using the given formatter. Read more

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

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

🔬 This is a nightly-only experimental API. (can_vector)

Determines if this Reader has an efficient read_vectored implementation. Read more

🔬 This is a nightly-only experimental API. (read_initializer)

Determines if this Reader 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

Transforms this Read instance to an Iterator over its bytes. Read more

Creates an adaptor which will chain this stream with another. Read more

Creates an adaptor which will read at most limit bytes from it. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.