use alloc::{collections::vec_deque::VecDeque, vec::Vec};
use sel4::{MessageInfo, cap::Endpoint};
use sel4_kit::slot_manager::LeafSlot;
use crate::slot::alloc_slot;
#[derive(Debug)]
pub struct IpcSaver {
queue: VecDeque<LeafSlot>,
free_slots: Vec<LeafSlot>,
}
impl IpcSaver {
pub const fn new() -> Self {
Self {
queue: VecDeque::new(),
free_slots: Vec::new(),
}
}
pub fn save_caller(&mut self) -> Result<(), sel4::Error> {
let slot = match self.free_slots.pop() {
Some(slot) => slot,
None => alloc_slot(),
};
slot.save_caller()?;
self.queue.push_back(slot);
Ok(())
}
pub fn reply_one(&mut self, msg: MessageInfo) -> Result<(), sel4::Error> {
let reply_cap = self.queue.pop_front();
if let Some(slot) = reply_cap {
Endpoint::from(slot).send(msg);
self.free_slots.push(slot);
}
Ok(())
}
pub fn queue_len(&self) -> usize {
self.queue.len()
}
}
impl Default for IpcSaver {
fn default() -> Self {
Self::new()
}
}