diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 651db6356ba07..ab4ae50c44367 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -12,7 +12,7 @@ reason = "futures in libcore are unstable", issue = "50547")] -use {fmt, mem}; +use fmt; use marker::Unpin; use ptr::NonNull; @@ -63,6 +63,20 @@ impl Waker { pub fn will_wake(&self, other: &Waker) -> bool { self.inner == other.inner } + + /// Returns whether or not this `Waker` and `other` `LocalWaker` awaken + /// the same task. + /// + /// This function works on a best-effort basis, and may return false even + /// when the `Waker`s would awaken the same task. However, if this function + /// returns true, it is guaranteed that the `Waker`s will awaken the same + /// task. + /// + /// This function is primarily used for optimization purposes. + #[inline] + pub fn will_wake_local(&self, other: &LocalWaker) -> bool { + self.will_wake(&other.0) + } } impl Clone for Waker { @@ -97,9 +111,8 @@ impl Drop for Waker { /// Task executors can use this type to implement more optimized singlethreaded wakeup /// behavior. #[repr(transparent)] -pub struct LocalWaker { - inner: NonNull, -} +#[derive(Clone)] +pub struct LocalWaker(Waker); impl Unpin for LocalWaker {} impl !Send for LocalWaker {} @@ -120,7 +133,16 @@ impl LocalWaker { /// on the current thread. #[inline] pub unsafe fn new(inner: NonNull) -> Self { - LocalWaker { inner } + LocalWaker(Waker::new(inner)) + } + + /// Borrows this `LocalWaker` as a `Waker`. + /// + /// `Waker` is nearly identical to `LocalWaker`, but is threadsafe + /// (implements `Send` and `Sync`). + #[inline] + pub fn as_waker(&self) -> &Waker { + &self.0 } /// Converts this `LocalWaker` into a `Waker`. @@ -129,13 +151,13 @@ impl LocalWaker { /// (implements `Send` and `Sync`). #[inline] pub fn into_waker(self) -> Waker { - self.into() + self.0 } /// Wake up the task associated with this `LocalWaker`. #[inline] pub fn wake(&self) { - unsafe { self.inner.as_ref().wake_local() } + unsafe { self.0.inner.as_ref().wake_local() } } /// Returns whether or not this `LocalWaker` and `other` `LocalWaker` awaken the same task. @@ -148,7 +170,7 @@ impl LocalWaker { /// This function is primarily used for optimization purposes. #[inline] pub fn will_wake(&self, other: &LocalWaker) -> bool { - self.inner == other.inner + self.0.will_wake(&other.0) } /// Returns whether or not this `LocalWaker` and `other` `Waker` awaken the same task. @@ -161,45 +183,24 @@ impl LocalWaker { /// This function is primarily used for optimization purposes. #[inline] pub fn will_wake_nonlocal(&self, other: &Waker) -> bool { - self.inner == other.inner + self.0.will_wake(other) } } impl From for Waker { #[inline] fn from(local_waker: LocalWaker) -> Self { - let inner = local_waker.inner; - mem::forget(local_waker); - Waker { inner } - } -} - -impl Clone for LocalWaker { - #[inline] - fn clone(&self) -> Self { - let waker = unsafe { self.inner.as_ref().clone_raw() }; - let inner = waker.inner; - mem::forget(waker); - LocalWaker { inner } + local_waker.0 } } impl fmt::Debug for LocalWaker { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Waker") + f.debug_struct("LocalWaker") .finish() } } -impl Drop for LocalWaker { - #[inline] - fn drop(&mut self) { - unsafe { - self.inner.as_ref().drop_raw() - } - } -} - /// An unsafe trait for implementing custom memory management for a `Waker` or `LocalWaker`. /// /// A `Waker` conceptually is a cloneable trait object for `Wake`, and is