summary refs log tree commit diff
path: root/library/alloc/src
diff options
context:
space:
mode:
authorYoshua Wuyts <yoshuawuyts@gmail.com>2021-01-22 18:06:26 +0100
committerYoshua Wuyts <yoshuawuyts@gmail.com>2021-02-03 16:54:29 +0100
commit2c8bf1db549d1e70af53b7ff8b8afb80187827e2 (patch)
tree8e6967ef1e7d649741a381b9e15ea2707cf9fd32 /library/alloc/src
parent6ad11e2e25919b75ebbc36d7910f2a1126a7e873 (diff)
downloadrust-2c8bf1db549d1e70af53b7ff8b8afb80187827e2.tar.gz
rust-2c8bf1db549d1e70af53b7ff8b8afb80187827e2.zip
Stabilize the Wake trait
Co-Authored-By: Ashley Mannix <kodraus@hey.com>
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/task.rs66
1 files changed, 59 insertions, 7 deletions
diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs
index a80550a9653..ab7611ae071 100644
--- a/library/alloc/src/task.rs
+++ b/library/alloc/src/task.rs
@@ -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)