mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-26 22:05:14 +00:00
Stabilize the Wake trait
Co-Authored-By: Ashley Mannix <kodraus@hey.com>
This commit is contained in:
parent
6ad11e2e25
commit
2c8bf1db54
@ -1,4 +1,4 @@
|
||||
#![unstable(feature = "wake_trait", issue = "69912")]
|
||||
#![stable(feature = "wake_trait", since = "1.51.0")]
|
||||
//! Types and Traits for working with asynchronous tasks.
|
||||
use core::mem::ManuallyDrop;
|
||||
use core::task::{RawWaker, RawWakerVTable, Waker};
|
||||
@ -16,18 +16,70 @@ use crate::sync::Arc;
|
||||
/// to wake up a task is stored in an [`Arc`]. Some executors (especially
|
||||
/// those for embedded systems) cannot use this API, which is why [`RawWaker`]
|
||||
/// exists as an alternative for those systems.
|
||||
#[unstable(feature = "wake_trait", issue = "69912")]
|
||||
///
|
||||
/// [arc]: ../../std/sync/struct.Arc.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// A basic `block_on` function that takes a future and runs it to completion on
|
||||
/// the current thread.
|
||||
///
|
||||
/// **Note:** This example trades correctness for simplicity. In order to prevent
|
||||
/// deadlocks, production-grade implementations will also need to handle
|
||||
/// intermediate calls to `thread::unpark` as well as nested invocations.
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::future::Future;
|
||||
/// use std::sync::Arc;
|
||||
/// use std::task::{Context, Poll, Wake};
|
||||
/// use std::thread::{self, Thread};
|
||||
///
|
||||
/// /// A waker that wakes up the current thread when called.
|
||||
/// struct ThreadWaker(Thread);
|
||||
///
|
||||
/// impl Wake for ThreadWaker {
|
||||
/// fn wake(self: Arc<Self>) {
|
||||
/// self.0.unpark();
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// /// Run a future to completion on the current thread.
|
||||
/// fn block_on<T>(fut: impl Future<Output = T>) -> T {
|
||||
/// // Pin the future so it can be polled.
|
||||
/// let mut fut = Box::pin(fut);
|
||||
///
|
||||
/// // Create a new context to be passed to the future.
|
||||
/// let t = thread::current();
|
||||
/// let waker = Arc::new(ThreadWaker(t)).into();
|
||||
/// let mut cx = Context::from_waker(&waker);
|
||||
///
|
||||
/// // Run the future to completion.
|
||||
/// loop {
|
||||
/// match fut.as_mut().poll(&mut cx) {
|
||||
/// Poll::Ready(res) => return res,
|
||||
/// Poll::Pending => thread::park(),
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// block_on(async {
|
||||
/// println!("Hi from inside a future!");
|
||||
/// });
|
||||
/// ```
|
||||
#[stable(feature = "wake_trait", since = "1.51.0")]
|
||||
pub trait Wake {
|
||||
/// Wake this task.
|
||||
#[unstable(feature = "wake_trait", issue = "69912")]
|
||||
#[stable(feature = "wake_trait", since = "1.51.0")]
|
||||
fn wake(self: Arc<Self>);
|
||||
|
||||
/// Wake this task without consuming the waker.
|
||||
///
|
||||
/// If an executor supports a cheaper way to wake without consuming the
|
||||
/// waker, it should override this method. By default, it clones the
|
||||
/// [`Arc`] and calls `wake` on the clone.
|
||||
#[unstable(feature = "wake_trait", issue = "69912")]
|
||||
/// [`Arc`] and calls [`wake`] on the clone.
|
||||
///
|
||||
/// [`wake`]: Wake::wake
|
||||
#[stable(feature = "wake_trait", since = "1.51.0")]
|
||||
fn wake_by_ref(self: &Arc<Self>) {
|
||||
self.clone().wake();
|
||||
}
|
||||
@ -35,7 +87,7 @@ pub trait Wake {
|
||||
|
||||
#[cfg_attr(bootstrap, allow(rustc::ineffective_unstable_trait_impl))]
|
||||
#[cfg_attr(not(bootstrap), allow(ineffective_unstable_trait_impl))]
|
||||
#[unstable(feature = "wake_trait", issue = "69912")]
|
||||
#[stable(feature = "wake_trait", since = "1.51.0")]
|
||||
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
|
||||
fn from(waker: Arc<W>) -> Waker {
|
||||
// SAFETY: This is safe because raw_waker safely constructs
|
||||
@ -46,7 +98,7 @@ impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
|
||||
|
||||
#[cfg_attr(bootstrap, allow(rustc::ineffective_unstable_trait_impl))]
|
||||
#[cfg_attr(not(bootstrap), allow(ineffective_unstable_trait_impl))]
|
||||
#[unstable(feature = "wake_trait", issue = "69912")]
|
||||
#[stable(feature = "wake_trait", since = "1.51.0")]
|
||||
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
|
||||
fn from(waker: Arc<W>) -> RawWaker {
|
||||
raw_waker(waker)
|
||||
|
@ -329,7 +329,6 @@
|
||||
#![feature(unwind_attributes)]
|
||||
#![feature(vec_into_raw_parts)]
|
||||
#![feature(vec_spare_capacity)]
|
||||
#![feature(wake_trait)]
|
||||
// NB: the above list is sorted to minimize merge conflicts.
|
||||
#![default_lib_allocator]
|
||||
|
||||
@ -508,7 +507,7 @@ pub mod task {
|
||||
pub use core::task::*;
|
||||
|
||||
#[doc(inline)]
|
||||
#[unstable(feature = "wake_trait", issue = "69912")]
|
||||
#[stable(feature = "wake_trait", since = "1.51.0")]
|
||||
pub use alloc::task::*;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
// edition:2018
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![feature(wake_trait)]
|
||||
use std::future::Future;
|
||||
use std::task::{Waker, Wake, Context};
|
||||
use std::sync::Arc;
|
||||
|
Loading…
Reference in New Issue
Block a user