-
Notifications
You must be signed in to change notification settings - Fork 634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implements the changes for Wakers that are currently discussed in the tracking issue for stabilization #1340
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,74 +1,56 @@ | ||||||
use futures_core::task::{LocalWaker, UnsafeWake, Wake, Waker}; | ||||||
use std::cell::UnsafeCell; | ||||||
use std::ptr::NonNull; | ||||||
use std::sync::Arc; | ||||||
use futures_core::task::{LocalWaker, RawWaker, RawWakerVTable}; | ||||||
use core::cell::UnsafeCell; | ||||||
use core::ptr::null; | ||||||
|
||||||
/// An implementation of [`Wake`](futures_core::task::Wake) that panics when | ||||||
/// woken. | ||||||
/// | ||||||
/// # Examples | ||||||
/// | ||||||
/// ```should_panic | ||||||
/// #![feature(futures_api)] | ||||||
/// use futures_test::task::panic_local_waker_ref; | ||||||
/// | ||||||
/// let lw = panic_local_waker_ref(); | ||||||
/// lw.wake(); // Will panic | ||||||
/// ``` | ||||||
#[derive(Debug)] | ||||||
pub struct PanicWake { | ||||||
_reserved: (), | ||||||
unsafe fn noop_clone(_data: *const()) -> RawWaker { | ||||||
raw_panic_waker() | ||||||
} | ||||||
|
||||||
impl PanicWake { | ||||||
/// Create a new instance | ||||||
pub fn new() -> Self { | ||||||
Self { _reserved: () } | ||||||
} | ||||||
unsafe fn noop(_data: *const()) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
You should be able to remove fn noop(_data: *const()) {}
const PTR: unsafe fn(*const ()) = noop; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting, so there’s a coercion from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that's just due to the lack of transitive coercions in general. It is not particular to this case AFAIK. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We generally accept PRs for these without FCP since the original RFC specified that we should include all transitive coercions, but there isn't a mechanism in the compiler for that today. |
||||||
} | ||||||
|
||||||
impl Default for PanicWake { | ||||||
fn default() -> Self { | ||||||
Self::new() | ||||||
} | ||||||
unsafe fn wake_panic(_data: *const()) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
ditto |
||||||
panic!("should not be woken"); | ||||||
} | ||||||
|
||||||
impl Wake for PanicWake { | ||||||
fn wake(_arc_self: &Arc<Self>) { | ||||||
panic!("should not be woken") | ||||||
} | ||||||
unsafe fn noop_into_waker(_data: *const()) -> Option<RawWaker> { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
ditto |
||||||
Some(raw_panic_waker()) | ||||||
} | ||||||
|
||||||
unsafe impl UnsafeWake for PanicWake { | ||||||
unsafe fn clone_raw(&self) -> Waker { | ||||||
panic_waker() | ||||||
} | ||||||
const PANIC_WAKER_VTABLE: RawWakerVTable = RawWakerVTable { | ||||||
clone: noop_clone, | ||||||
drop_fn: noop, | ||||||
wake: wake_panic, | ||||||
into_waker: noop_into_waker, | ||||||
}; | ||||||
|
||||||
unsafe fn drop_raw(&self) {} | ||||||
|
||||||
unsafe fn wake(&self) { | ||||||
panic!("should not be woken") | ||||||
fn raw_panic_waker() -> RawWaker { | ||||||
RawWaker { | ||||||
data: null(), | ||||||
vtable: &PANIC_WAKER_VTABLE, | ||||||
} | ||||||
} | ||||||
|
||||||
fn panic_unsafe_wake() -> NonNull<dyn UnsafeWake> { | ||||||
static mut INSTANCE: PanicWake = PanicWake { _reserved: () }; | ||||||
unsafe { NonNull::new_unchecked(&mut INSTANCE as *mut dyn UnsafeWake) } | ||||||
} | ||||||
|
||||||
fn panic_waker() -> Waker { | ||||||
unsafe { Waker::new(panic_unsafe_wake()) } | ||||||
} | ||||||
|
||||||
/// Create a new [`LocalWaker`](futures_core::task::LocalWaker) referencing | ||||||
/// a singleton instance of [`PanicWake`]. | ||||||
/// Create a new [`LocalWaker`](futures_core::task::LocalWaker) which will | ||||||
/// panic when `wake()` is called on it. The [`LocalWaker`] can be converted | ||||||
/// into a [`Waker`] which will behave the same way. | ||||||
/// | ||||||
/// # Examples | ||||||
/// | ||||||
/// ```should_panic | ||||||
/// #![feature(futures_api)] | ||||||
/// use futures_test::task::panic_local_waker; | ||||||
/// | ||||||
/// let lw = panic_local_waker(); | ||||||
/// lw.wake(); // Will panic | ||||||
/// ``` | ||||||
pub fn panic_local_waker() -> LocalWaker { | ||||||
unsafe { LocalWaker::new(panic_unsafe_wake()) } | ||||||
unsafe { LocalWaker::new_unchecked(raw_panic_waker()) } | ||||||
} | ||||||
|
||||||
/// Get a thread local reference to a | ||||||
/// Get a global reference to a | ||||||
/// [`LocalWaker`](futures_core::task::LocalWaker) referencing a singleton | ||||||
/// instance of [`PanicWake`]. | ||||||
/// instance of a [`LocalWaker`] which panics when woken. | ||||||
/// | ||||||
/// # Examples | ||||||
/// | ||||||
|
@@ -82,8 +64,8 @@ pub fn panic_local_waker() -> LocalWaker { | |||||
/// ``` | ||||||
pub fn panic_local_waker_ref() -> &'static LocalWaker { | ||||||
thread_local! { | ||||||
static LOCAL_WAKER_INSTANCE: UnsafeCell<LocalWaker> = | ||||||
static PANIC_WAKER_INSTANCE: UnsafeCell<LocalWaker> = | ||||||
UnsafeCell::new(panic_local_waker()); | ||||||
} | ||||||
LOCAL_WAKER_INSTANCE.with(|l| unsafe { &*l.get() }) | ||||||
PANIC_WAKER_INSTANCE.with(|l| unsafe { &*l.get() }) | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto