pub struct ProdIter<B: MutRB<T>, T> { /* private fields */ }Expand description
Implementations§
source§impl<B: MutRB<T>, T> ProdIter<B, T>
impl<B: MutRB<T>, T> ProdIter<B, T>
sourcepub fn is_work_alive(&self) -> bool
pub fn is_work_alive(&self) -> bool
Returns true if the worker iterator is still alive, false if it has been dropped.
Note: when the buffer is used in non-mutable mode this will always return false.
sourcepub fn is_cons_alive(&self) -> bool
pub fn is_cons_alive(&self) -> bool
Returns true if the consumer iterator is still alive, false if it has been dropped.
sourcepub fn push(&mut self, value: T) -> Result<(), T>
pub fn push(&mut self, value: T) -> Result<(), T>
Tries to push a new item by moving or copying it.
Returns:
Err(value), if the buffer is full;Ok(()), otherwise.
Examples found in repository?
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
fn f() {
let buf = ConcurrentHeapRB::from(vec![0; RB_SIZE]);
let (mut prod, mut cons) = buf.split();
// Flag variable to stop threads
let stop = Arc::new(AtomicBool::new(false));
let stop_clone = stop.clone();
// An infinite stream of data
let producer = thread::spawn(move || {
let mut produced = vec![];
let mut counter = 0;
while !stop_clone.load(Acquire) {
if prod.push(counter).is_ok() {
// Store produced values to check them later
produced.push(counter);
// Reset counter to avoid overflow
if counter < u8::MAX { counter += 1; } else { counter = 0; }
}
}
// Iterator has to be returned here, as it was moved at the beginning of the thread
(prod, produced)
});
let stop_clone = stop.clone();
let consumer = thread::spawn(move || {
let mut consumed = vec![];
while !stop_clone.load(Acquire) {
// Store consumed values to check them later
if let Some(value) = cons.pop() { consumed.push(value); }
}
// Iterator has to be returned here, as it was moved at the beginning of the thread
(cons, consumed)
});
// Let threads run for a while...
thread::sleep(Duration::from_millis(1));
// Stop threads
stop.store(true, Release);
let (_prod, produced) = producer.join().unwrap();
let (mut cons, mut consumed) = consumer.join().unwrap();
// Consume the remaining part of the buffer
if let Some((head, tail)) = cons.peek_available() {
consumed.extend_from_slice(head);
consumed.extend_from_slice(tail);
}
assert_eq!(produced, consumed)
}sourcepub fn push_slice(&mut self, slice: &[T]) -> Option<()>where
T: Copy,
pub fn push_slice(&mut self, slice: &[T]) -> Option<()>where
T: Copy,
Tries to push a slice of items by copying the elements.
The elements must implement Copy trait.
Returns:
None, if the buffer is full;Some(()), otherwise.
sourcepub fn push_slice_clone(&mut self, slice: &[T]) -> Option<()>where
T: Clone,
pub fn push_slice_clone(&mut self, slice: &[T]) -> Option<()>where
T: Clone,
Tries to push a slice of items by cloning the elements.
The elements must implement Clone trait.
Returns:
None, if the buffer is full;Some(()), otherwise.
sourcepub unsafe fn get_next_item_mut(&mut self) -> Option<&mut T>
pub unsafe fn get_next_item_mut(&mut self) -> Option<&mut T>
If available, returns a mutable reference to the next item. This reference can be used to write data into an initialised item.
Items can be initialised by calling Self::get_next_item_mut_init or by creating a buffer
using default constructor. E.g.: [ConcurrentHeapRB::default] or [LocalStackRB::default].
For uninitialised items, use Self::get_next_item_mut_init, instead.
Being this a reference, Self::advance() has to be called when done with the mutation
in order to move the iterator.
§Safety
The retrieved item must be initialised! For more info, refer to [MaybeUninit::assume_init_mut].
sourcepub fn get_next_item_mut_init(&mut self) -> Option<*mut T>
pub fn get_next_item_mut_init(&mut self) -> Option<*mut T>
If available, returns a mutable pointer to the next item. This pointer can be used to write data into the item, even if this is not already initialised. It is important to note that reading from this pointer or turning it into a reference is still undefined behavior, unless the item is initialized.
For more info, refer to [MaybeUninit::as_mut_ptr].
Being this a pointer, Self::advance() has to be called when done with the mutation
in order to move the iterator.