pub struct QueueInner<T, S: Storage> { /* private fields */ }
Expand description
Implementations§
Source§impl<T, const N: usize> QueueInner<T, OwnedStorage<N>>
impl<T, const N: usize> QueueInner<T, OwnedStorage<N>>
Source§impl<T, S: Storage> QueueInner<T, S>
impl<T, S: Storage> QueueInner<T, S>
Sourcepub fn as_view(&self) -> &QueueView<T>
pub fn as_view(&self) -> &QueueView<T>
Get a reference to the Queue
, erasing the N
const-generic.
Sourcepub fn as_mut_view(&mut self) -> &mut QueueView<T>
pub fn as_mut_view(&mut self) -> &mut QueueView<T>
Get a mutable reference to the Queue
, erasing the N
const-generic.
Sourcepub fn iter_mut(&mut self) -> IterMut<'_, T> ⓘ
pub fn iter_mut(&mut self) -> IterMut<'_, T> ⓘ
Returns an iterator that allows modifying each value.
Sourcepub fn enqueue(&mut self, item: T) -> Result<(), T>
pub fn enqueue(&mut self, item: T) -> Result<(), T>
Adds an item
to the end of the queue.
Returns back the item
if the queue is full.
Sourcepub fn dequeue(&mut self) -> Option<T>
pub fn dequeue(&mut self) -> Option<T>
Returns the item in the front of the queue, or None
if the queue is empty.
Sourcepub fn peek(&self) -> Option<&T>
pub fn peek(&self) -> Option<&T>
Returns a reference to the item in the front of the queue without dequeuing it, or
None
if the queue is empty.
§Examples
use heapless::spsc::Queue;
let mut queue: Queue<u8, 235> = Queue::new();
let (mut producer, mut consumer) = queue.split();
assert_eq!(None, consumer.peek());
producer.enqueue(1);
assert_eq!(Some(&1), consumer.peek());
assert_eq!(Some(1), consumer.dequeue());
assert_eq!(None, consumer.peek());
Sourcepub unsafe fn enqueue_unchecked(&mut self, item: T)
pub unsafe fn enqueue_unchecked(&mut self, item: T)
Adds an item
to the end of the queue, without checking if it’s full.
§Safety
If the queue is full, this operation will leak a value (T
’s destructor won’t run on
the value that got overwritten by item
), and will allow the dequeue
operation
to create a copy of item
, which could result in T
’s destructor running on item
twice.
Sourcepub unsafe fn dequeue_unchecked(&mut self) -> T
pub unsafe fn dequeue_unchecked(&mut self) -> T
Returns the item in the front of the queue, without checking if there is something in the queue.
§Safety
The queue must not be empty. Calling this on an empty queue causes undefined behavior.
Sourcepub fn split(&mut self) -> (Producer<'_, T>, Consumer<'_, T>)
pub fn split(&mut self) -> (Producer<'_, T>, Consumer<'_, T>)
Splits a queue into producer and consumer endpoints.
If you need this function in a const
context,
check out Queue::split_const
and QueueView::split_const
.
§Examples
Create a queue and split it at runtime
let mut queue: Queue<(), 4> = Queue::new();
let (mut producer, mut consumer) = queue.split();
producer.enqueue(()).unwrap();
assert_eq!(consumer.dequeue(), Some(()));
Create a queue at compile time, split it at runtime, and pass it to an interrupt handler via a mutex.
use core::cell::RefCell;
use critical_section::Mutex;
use heapless::spsc::{Producer, Queue};
static PRODUCER: Mutex<RefCell<Option<Producer<'static, ()>>>> =
{ Mutex::new(RefCell::new(None)) };
fn interrupt() {
let mut producer = {
static mut P: Option<Producer<'static, ()>> = None;
// SAFETY: Mutable access to `P` is allowed exclusively in this scope
// and `interrupt` cannot be called directly or preempt itself.
unsafe { &mut P }
}
.get_or_insert_with(|| {
critical_section::with(|cs| PRODUCER.borrow_ref_mut(cs).take().unwrap())
});
producer.enqueue(()).unwrap();
}
fn main() {
let mut consumer = {
let (p, c) = {
static mut Q: Queue<(), 4> = Queue::new();
// SAFETY: `Q` is only accessible in this scope
// and `main` is only called once.
#[allow(static_mut_refs)]
unsafe {
Q.split()
}
};
critical_section::with(move |cs| {
let mut producer = PRODUCER.borrow_ref_mut(cs);
*producer = Some(p);
});
c
};
// Interrupt occurs.
consumer.dequeue().unwrap();
}
Source§impl<T, const N: usize> QueueInner<T, OwnedStorage<N>>
impl<T, const N: usize> QueueInner<T, OwnedStorage<N>>
Sourcepub const fn split_const(&mut self) -> (Producer<'_, T>, Consumer<'_, T>)
pub const fn split_const(&mut self) -> (Producer<'_, T>, Consumer<'_, T>)
Splits a queue into producer and consumer endpoints.
Unlike Queue::split
, this method can be used in a const
context
§Example
Create and split a queue at compile time, and pass it to the main function and an interrupt handler via a mutex at runtime.
use core::cell::RefCell;
use critical_section::Mutex;
use heapless::spsc::{Consumer, Producer, Queue};
static PC: (
Mutex<RefCell<Option<Producer<'_, ()>>>>,
Mutex<RefCell<Option<Consumer<'_, ()>>>>,
) = {
static mut Q: Queue<(), 4> = Queue::new();
// SAFETY: `Q` is only accessible in this scope.
#[allow(static_mut_refs)]
let (p, c) = unsafe { Q.split_const() };
(
Mutex::new(RefCell::new(Some(p))),
Mutex::new(RefCell::new(Some(c))),
)
};
fn interrupt() {
let mut producer = {
static mut P: Option<Producer<'_, ()>> = None;
// SAFETY: Mutable access to `P` is allowed exclusively in this scope
// and `interrupt` cannot be called directly or preempt itself.
unsafe { &mut P }
}
.get_or_insert_with(|| {
critical_section::with(|cs| PC.0.borrow_ref_mut(cs).take().unwrap())
});
producer.enqueue(()).unwrap();
}
fn main() {
let mut consumer = critical_section::with(|cs| PC.1.borrow_ref_mut(cs).take().unwrap());
// Interrupt occurs.
consumer.dequeue().unwrap();
}
Source§impl<T> QueueInner<T, ViewStorage>
impl<T> QueueInner<T, ViewStorage>
Sourcepub const fn split_const(&mut self) -> (Producer<'_, T>, Consumer<'_, T>)
pub const fn split_const(&mut self) -> (Producer<'_, T>, Consumer<'_, T>)
Splits a queue into producer and consumer endpoints.
Unlike Queue::split
, this method can be used in a const
context
§Example
Create and split a queue at compile time, and pass it to the main function and an interrupt handler via a mutex at runtime.
use core::cell::RefCell;
use critical_section::Mutex;
use heapless::spsc::{Consumer, Producer, Queue, QueueView};
static PC: (
Mutex<RefCell<Option<Producer<'_, ()>>>>,
Mutex<RefCell<Option<Consumer<'_, ()>>>>,
) = {
static mut Q: &mut QueueView<()> = &mut Queue::<(), 4>::new();
// SAFETY: `Q` is only accessible in this scope.
#[allow(static_mut_refs)]
let (p, c) = unsafe { Q.split_const() };
(
Mutex::new(RefCell::new(Some(p))),
Mutex::new(RefCell::new(Some(c))),
)
};
fn interrupt() {
let mut producer = {
static mut P: Option<Producer<'_, ()>> = None;
// SAFETY: Mutable access to `P` is allowed exclusively in this scope
// and `interrupt` cannot be called directly or preempt itself.
unsafe { &mut P }
}
.get_or_insert_with(|| {
critical_section::with(|cs| PC.0.borrow_ref_mut(cs).take().unwrap())
});
producer.enqueue(()).unwrap();
}
fn main() {
let mut consumer = critical_section::with(|cs| PC.1.borrow_ref_mut(cs).take().unwrap());
// Interrupt occurs.
consumer.dequeue().unwrap();
}