sync: improve safety comments for WakeList (#6200)

This commit is contained in:
Alice Ryhl 2023-12-08 18:57:01 +01:00 committed by GitHub
parent e05d0f8c2c
commit c9273f1aee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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<Waker>; NUM_WAKERS],
curr: usize,
@ -11,14 +16,10 @@ pub(crate) struct WakeList {
impl WakeList {
pub(crate) fn new() -> Self {
const UNINIT_WAKER: MaybeUninit<Waker> = 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::<Waker>(), self.curr);
// SAFETY: The first `curr` elements are initialized, so we can drop them.
unsafe { ptr::drop_in_place(slice) };
}
}