1use core::mem::MaybeUninit;
2use core::ptr;
3use std::task::Waker;
4
5const NUM_WAKERS: usize = 32;
6
7pub(crate) struct WakeList {
8 inner: [MaybeUninit<Waker>; NUM_WAKERS],
9 curr: usize,
10}
11
12impl WakeList {
13 pub(crate) fn new() -> Self {
14 Self {
15 inner: unsafe {
16 // safety: Create an uninitialized array of `MaybeUninit`. The
17 // `assume_init` is safe because the type we are claiming to
18 // have initialized here is a bunch of `MaybeUninit`s, which do
19 // not require initialization.
20 MaybeUninit::uninit().assume_init()
21 },
22 curr: 0,
23 }
24 }
25
26 #[inline]
27 pub(crate) fn can_push(&self) -> bool {
28 self.curr < NUM_WAKERS
29 }
30
31 pub(crate) fn push(&mut self, val: Waker) {
32 debug_assert!(self.can_push());
33
34 self.inner[self.curr] = MaybeUninit::new(val);
35 self.curr += 1;
36 }
37
38 pub(crate) fn wake_all(&mut self) {
39 assert!(self.curr <= NUM_WAKERS);
40 while self.curr > 0 {
41 self.curr -= 1;
42 let waker = unsafe { ptr::read(self.inner[self.curr].as_mut_ptr()) };
43 waker.wake();
44 }
45 }
46}
47
48impl Drop for WakeList {
49 fn drop(&mut self) {
50 let slice: *mut [Waker] = ptr::slice_from_raw_parts_mut(self.inner.as_mut_ptr() as *mut Waker, self.curr);
51 unsafe { ptr::drop_in_place(to_drop:slice) };
52 }
53}
54