Skip to content

Commit

Permalink
sync: drop wakers after unlocking in Notify
Browse files Browse the repository at this point in the history
  • Loading branch information
Darksonn committed Feb 18, 2023
1 parent 24aac0a commit e124f51
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions tokio/src/sync/notify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -829,10 +829,17 @@ impl Notified<'_> {
}
}

let mut old_waker = None;
if waker.is_some() {
// Safety: called while locked.
//
// This code makes the following assignment, but it
// stores the old waker in `old_waker` so that we can
// drop it after releasing the mutex.
//
// (*waiter.get()).waker = waker;
unsafe {
(*waiter.get()).waker = waker;
old_waker = std::mem::replace(&mut (*waiter.get()).waker, waker);
}
}

Expand All @@ -843,6 +850,9 @@ impl Notified<'_> {

*state = Waiting;

drop(waiters);
drop(old_waker);

return Poll::Pending;
}
Waiting => {
Expand All @@ -855,11 +865,12 @@ impl Notified<'_> {

// Safety: called while locked
let w = unsafe { &mut *waiter.get() };
let mut old_waker = None;

if w.notified.is_some() {
// Our waker has been notified. Reset the fields and
// remove it from the list.
w.waker = None;
old_waker = std::mem::take(&mut w.waker);
w.notified = None;

*state = Done;
Expand All @@ -871,10 +882,14 @@ impl Notified<'_> {
None => true,
};
if should_update {
w.waker = Some(waker.clone());
old_waker = std::mem::replace(&mut w.waker, Some(waker.clone()));
}
}

// Drop the old waker after releasing the lock.
drop(waiters);
drop(old_waker);

return Poll::Pending;
}

Expand All @@ -884,6 +899,9 @@ impl Notified<'_> {
// is helpful to visualize the scope of the critical
// section.
drop(waiters);

// Drop the old waker after releasing the lock.
drop(old_waker);
}
Done => {
return Poll::Ready(());
Expand Down

0 comments on commit e124f51

Please sign in to comment.