From c9273f1aee9927b16ee3a789a382c99ad600c8b6 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Fri, 8 Dec 2023 18:57:01 +0100 Subject: [PATCH] sync: improve safety comments for `WakeList` (#6200) --- tokio/src/util/wake_list.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/tokio/src/util/wake_list.rs b/tokio/src/util/wake_list.rs index aa569dd17b6..c5f432b0bb8 100644 --- a/tokio/src/util/wake_list.rs +++ b/tokio/src/util/wake_list.rs @@ -4,6 +4,11 @@ use std::task::Waker; const NUM_WAKERS: usize = 32; +/// A list of wakers to be woken. +/// +/// # Invariants +/// +/// The first `curr` elements of `inner` are initialized. pub(crate) struct WakeList { inner: [MaybeUninit; NUM_WAKERS], curr: usize, @@ -11,14 +16,10 @@ pub(crate) struct WakeList { impl WakeList { pub(crate) fn new() -> Self { + const UNINIT_WAKER: MaybeUninit = MaybeUninit::uninit(); + Self { - inner: unsafe { - // safety: Create an uninitialized array of `MaybeUninit`. The - // `assume_init` is safe because the type we are claiming to - // have initialized here is a bunch of `MaybeUninit`s, which do - // not require initialization. - MaybeUninit::uninit().assume_init() - }, + inner: [UNINIT_WAKER; NUM_WAKERS], curr: 0, } } @@ -39,6 +40,8 @@ impl WakeList { assert!(self.curr <= NUM_WAKERS); while self.curr > 0 { self.curr -= 1; + // SAFETY: The first `curr` elements of `WakeList` are initialized, so by decrementing + // `curr`, we can take ownership of the last item. let waker = unsafe { ptr::read(self.inner[self.curr].as_mut_ptr()) }; waker.wake(); } @@ -47,7 +50,9 @@ impl WakeList { impl Drop for WakeList { fn drop(&mut self) { - let slice = ptr::slice_from_raw_parts_mut(self.inner.as_mut_ptr() as *mut Waker, self.curr); + let slice = + ptr::slice_from_raw_parts_mut(self.inner.as_mut_ptr().cast::(), self.curr); + // SAFETY: The first `curr` elements are initialized, so we can drop them. unsafe { ptr::drop_in_place(slice) }; } }