Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions local-waker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible, missing_docs)]

use core::{cell::Cell, fmt, marker::PhantomData, task::Waker};
use core::{cell::UnsafeCell, fmt, marker::PhantomData, task::Waker};

/// A synchronization primitive for task wakeup.
///
Expand All @@ -27,7 +27,7 @@ use core::{cell::Cell, fmt, marker::PhantomData, task::Waker};
/// [`wake`]: LocalWaker::wake
#[derive(Default)]
pub struct LocalWaker {
pub(crate) waker: Cell<Option<Waker>>,
pub(crate) waker: UnsafeCell<Option<Waker>>,
// mark LocalWaker as a !Send type.
_phantom: PhantomData<*const ()>,
}
Expand All @@ -43,8 +43,15 @@ impl LocalWaker {
/// Returns `true` if waker was registered before.
#[inline]
pub fn register(&self, waker: &Waker) -> bool {
let last_waker = self.waker.replace(Some(waker.clone()));
last_waker.is_some()
let mut registered = false;
if let Some(prev) = unsafe { &*self.waker.get() } {
if waker.will_wake(prev) {
return true;
}
registered = true;
}
unsafe { *self.waker.get() = Some(waker.clone()) }
registered
}

/// Calls `wake` on the last `Waker` passed to `register`.
Expand All @@ -62,7 +69,7 @@ impl LocalWaker {
/// If a waker has not been registered, this returns `None`.
#[inline]
pub fn take(&self) -> Option<Waker> {
self.waker.take()
unsafe { (*self.waker.get()).take() }
Comment on lines -65 to +72
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Safety note should be added.

}
}

Expand Down