use std::task::Context;
use std::task::Waker;
use slab::Slab;
#[derive(Debug)]
pub(crate) struct WaitSet {
waiters: Slab<Waker>,
}
impl WaitSet {
pub const fn new() -> Self {
Self {
waiters: Slab::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
waiters: Slab::with_capacity(capacity),
}
}
pub(crate) fn wake_all(&mut self) {
for w in self.waiters.drain() {
w.wake();
}
}
pub(crate) fn register_waker(&mut self, idx: &mut Option<usize>, cx: &mut Context<'_>) {
match *idx {
None => {
let key = self.waiters.insert(cx.waker().clone());
*idx = Some(key);
}
Some(key) => {
if self.waiters.contains(key) {
if !self.waiters[key].will_wake(cx.waker()) {
self.waiters[key] = cx.waker().clone();
}
} else {
let key = self.waiters.insert(cx.waker().clone());
*idx = Some(key);
}
}
}
}
}