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 { new() -> Self13 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] can_push(&self) -> bool27 pub(crate) fn can_push(&self) -> bool { 28 self.curr < NUM_WAKERS 29 } 30 push(&mut self, val: Waker)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 wake_all(&mut self)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 { drop(&mut self)49 fn drop(&mut self) { 50 let slice = ptr::slice_from_raw_parts_mut(self.inner.as_mut_ptr() as *mut Waker, self.curr); 51 unsafe { ptr::drop_in_place(slice) }; 52 } 53 } 54