use alloc::vec::Vec;
use slab::Slab;
use wasi::io::poll::{poll, Pollable};
#[derive(Debug)]
pub(crate) struct Poller {
pub(crate) targets: Slab<Pollable>,
}
impl Poller {
pub(crate) fn new() -> Self {
Self::with_capacity(0)
}
pub(crate) fn with_capacity(capacity: usize) -> Self {
Self {
targets: Slab::with_capacity(capacity),
}
}
pub(crate) fn insert(&mut self, target: Pollable) -> EventKey {
let key = self.targets.insert(target);
EventKey(key as u32)
}
pub(crate) fn get(&self, key: &EventKey) -> Option<&Pollable> {
self.targets.get(key.0 as usize)
}
pub(crate) fn remove(&mut self, key: EventKey) -> Option<Pollable> {
self.targets.try_remove(key.0 as usize)
}
pub(crate) fn block_until(&mut self) -> Vec<EventKey> {
let mut indexes = Vec::with_capacity(self.targets.len());
let mut targets = Vec::with_capacity(self.targets.len());
for (index, target) in self.targets.iter() {
indexes.push(index);
targets.push(target);
}
debug_assert_ne!(
targets.len(),
0,
"Attempting to block on an empty list of pollables - without any pending work, no progress can be made and the program may spin indefinitely"
);
let ready_indexes = poll(&targets);
ready_indexes
.into_iter()
.map(|index| EventKey(indexes[index as usize] as u32))
.collect()
}
}
#[repr(transparent)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
pub(crate) struct EventKey(pub(crate) u32);