Skip to content

Commit

Permalink
util: make WakeList::wake_all use FIFO ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
paolobarbolini committed Apr 29, 2024
1 parent d33fdd8 commit 116dd5f
Showing 1 changed file with 28 additions and 6 deletions.
34 changes: 28 additions & 6 deletions tokio/src/util/wake_list.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::mem::MaybeUninit;
use core::mem::{self, MaybeUninit};
use core::ptr;
use std::task::Waker;

Expand Down Expand Up @@ -37,12 +37,34 @@ impl WakeList {
}

pub(crate) fn wake_all(&mut self) {
struct DropGuard {
wakers: *mut Waker,
start: usize,
end: usize,
}

impl Drop for DropGuard {
fn drop(&mut self) {
let slice = ptr::slice_from_raw_parts_mut(
unsafe { self.wakers.add(self.start) },
self.end - self.start,
);
// SAFETY: Elements in `start..end` are initialized, so we can drop them.
unsafe { ptr::drop_in_place(slice) };
}
}

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()) };

let mut guard = DropGuard {
wakers: self.inner.as_mut_ptr().cast::<Waker>(),
start: 0,
end: mem::take(&mut self.curr),
};
while guard.start < guard.end {
// SAFETY: Elements between `start..end` are initialized.
let waker = unsafe { ptr::read(guard.wakers.add(guard.start)) };
guard.start += 1;
waker.wake();
}
}
Expand Down

0 comments on commit 116dd5f

Please sign in to comment.