1 | use core::mem::MaybeUninit; |
2 | use core::ptr; |
3 | use std::task::Waker; |
4 | |
5 | const NUM_WAKERS: usize = 32; |
6 | |
7 | pub(crate) struct WakeList { |
8 | inner: [MaybeUninit<Waker>; NUM_WAKERS], |
9 | curr: usize, |
10 | } |
11 | |
12 | impl 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 | |
48 | impl 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 | |