Auto merge of #54732 - cramertj:waker, r=aturon

LocalWaker and Waker cleanups

r? @aturon
This commit is contained in:
bors 2018-10-10 18:28:30 +00:00
commit 5af0bb8304

View file

@ -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<dyn UnsafeWake>,
}
#[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<dyn UnsafeWake>) -> 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<LocalWaker> 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