use alloc::{boxed::Box, collections::vec_deque::VecDeque};
use core::array;
use crate::{SignalInfo, SignalSet};
pub struct PendingSignals {
pub set: SignalSet,
info_std: [Option<Box<SignalInfo>>; 32],
info_rt: [VecDeque<SignalInfo>; 33],
}
impl Default for PendingSignals {
fn default() -> Self {
Self {
set: SignalSet::default(),
info_std: Default::default(),
info_rt: array::from_fn(|_| VecDeque::new()),
}
}
}
impl PendingSignals {
pub fn put_signal(&mut self, sig: SignalInfo) -> bool {
let signo = sig.signo();
let added = self.set.add(signo);
if signo.is_realtime() {
self.info_rt[signo as usize - 32].push_back(sig);
} else {
if !added {
return false;
}
self.info_std[signo as usize] = Some(Box::new(sig));
}
true
}
pub fn dequeue_signal(&mut self, mask: &SignalSet) -> Option<SignalInfo> {
self.set.dequeue(mask).and_then(|signo| {
if signo.is_realtime() {
let queue = &mut self.info_rt[signo as usize - 32];
let result = queue.pop_front();
if !queue.is_empty() {
self.set.add(signo);
}
result
} else {
self.info_std[signo as usize].take().map(|boxed| *boxed)
}
})
}
}