From 1cda61fbda205920517f7b63af90c97c38ff9af6 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sat, 18 Feb 2023 09:43:06 +0100 Subject: Make some linked list operations unsafe, and document their safety at usage --- rtic-arbiter/src/lib.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'rtic-arbiter/src') diff --git a/rtic-arbiter/src/lib.rs b/rtic-arbiter/src/lib.rs index 09d1b2ee..c70fbf57 100644 --- a/rtic-arbiter/src/lib.rs +++ b/rtic-arbiter/src/lib.rs @@ -54,7 +54,8 @@ impl Arbiter { pub async fn access(&self) -> ExclusiveAccess<'_, T> { let mut link_ptr: Option> = None; - // Make this future `Drop`-safe, also shadow the original definition so we can't abuse it. + // Make this future `Drop`-safe. + // SAFETY(link_ptr): Shadow the original definition of `link_ptr` so we can't abuse it. let mut link_ptr = LinkPtr(&mut link_ptr as *mut Option>); let mut link_ptr2 = link_ptr.clone(); @@ -89,10 +90,13 @@ impl Arbiter { // Place the link in the wait queue on first run. let link_ref = link.insert(Link::new(cx.waker().clone())); - // SAFETY: The address to the link is stable as it is hidden behind - // `link_ptr`, and `link_ptr` shadows the original making it unmovable. - self.wait_queue - .push(unsafe { Pin::new_unchecked(link_ref) }); + // SAFETY(new_unchecked): The address to the link is stable as it is defined + // outside this stack frame. + // SAFETY(push): `link_ref` lifetime comes from `link_ptr` that is shadowed, + // and we make sure in `dropper` that the link is removed from the queue + // before dropping `link_ptr` AND `dropper` makes sure that the shadowed + // `link_ptr` lives until the end of the stack frame. + unsafe { self.wait_queue.push(Pin::new_unchecked(link_ref)) }; } Poll::Pending -- cgit v1.2.3