Skip to content

Commit 2c8bf1d

Browse files
yoshuawuytsKodrAus
andcommitted
Stabilize the Wake trait
Co-Authored-By: Ashley Mannix <kodraus@hey.com>
1 parent 6ad11e2 commit 2c8bf1d

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

library/alloc/src/task.rs

+59-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![unstable(feature = "wake_trait", issue = "69912")]
1+
#![stable(feature = "wake_trait", since = "1.51.0")]
22
//! Types and Traits for working with asynchronous tasks.
33
use core::mem::ManuallyDrop;
44
use core::task::{RawWaker, RawWakerVTable, Waker};
@@ -16,26 +16,78 @@ use crate::sync::Arc;
1616
/// to wake up a task is stored in an [`Arc`]. Some executors (especially
1717
/// those for embedded systems) cannot use this API, which is why [`RawWaker`]
1818
/// exists as an alternative for those systems.
19-
#[unstable(feature = "wake_trait", issue = "69912")]
19+
///
20+
/// [arc]: ../../std/sync/struct.Arc.html
21+
///
22+
/// # Examples
23+
///
24+
/// A basic `block_on` function that takes a future and runs it to completion on
25+
/// the current thread.
26+
///
27+
/// **Note:** This example trades correctness for simplicity. In order to prevent
28+
/// deadlocks, production-grade implementations will also need to handle
29+
/// intermediate calls to `thread::unpark` as well as nested invocations.
30+
///
31+
/// ```rust
32+
/// use std::future::Future;
33+
/// use std::sync::Arc;
34+
/// use std::task::{Context, Poll, Wake};
35+
/// use std::thread::{self, Thread};
36+
///
37+
/// /// A waker that wakes up the current thread when called.
38+
/// struct ThreadWaker(Thread);
39+
///
40+
/// impl Wake for ThreadWaker {
41+
/// fn wake(self: Arc<Self>) {
42+
/// self.0.unpark();
43+
/// }
44+
/// }
45+
///
46+
/// /// Run a future to completion on the current thread.
47+
/// fn block_on<T>(fut: impl Future<Output = T>) -> T {
48+
/// // Pin the future so it can be polled.
49+
/// let mut fut = Box::pin(fut);
50+
///
51+
/// // Create a new context to be passed to the future.
52+
/// let t = thread::current();
53+
/// let waker = Arc::new(ThreadWaker(t)).into();
54+
/// let mut cx = Context::from_waker(&waker);
55+
///
56+
/// // Run the future to completion.
57+
/// loop {
58+
/// match fut.as_mut().poll(&mut cx) {
59+
/// Poll::Ready(res) => return res,
60+
/// Poll::Pending => thread::park(),
61+
/// }
62+
/// }
63+
/// }
64+
///
65+
/// block_on(async {
66+
/// println!("Hi from inside a future!");
67+
/// });
68+
/// ```
69+
#[stable(feature = "wake_trait", since = "1.51.0")]
2070
pub trait Wake {
2171
/// Wake this task.
22-
#[unstable(feature = "wake_trait", issue = "69912")]
72+
#[stable(feature = "wake_trait", since = "1.51.0")]
2373
fn wake(self: Arc<Self>);
2474

2575
/// Wake this task without consuming the waker.
2676
///
2777
/// If an executor supports a cheaper way to wake without consuming the
2878
/// waker, it should override this method. By default, it clones the
29-
/// [`Arc`] and calls `wake` on the clone.
30-
#[unstable(feature = "wake_trait", issue = "69912")]
79+
/// [`Arc`] and calls [`wake`] on the clone.
80+
///
81+
/// [`wake`]: Wake::wake
82+
#[stable(feature = "wake_trait", since = "1.51.0")]
3183
fn wake_by_ref(self: &Arc<Self>) {
3284
self.clone().wake();
3385
}
3486
}
3587

3688
#[cfg_attr(bootstrap, allow(rustc::ineffective_unstable_trait_impl))]
3789
#[cfg_attr(not(bootstrap), allow(ineffective_unstable_trait_impl))]
38-
#[unstable(feature = "wake_trait", issue = "69912")]
90+
#[stable(feature = "wake_trait", since = "1.51.0")]
3991
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
4092
fn from(waker: Arc<W>) -> Waker {
4193
// SAFETY: This is safe because raw_waker safely constructs
@@ -46,7 +98,7 @@ impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
4698

4799
#[cfg_attr(bootstrap, allow(rustc::ineffective_unstable_trait_impl))]
48100
#[cfg_attr(not(bootstrap), allow(ineffective_unstable_trait_impl))]
49-
#[unstable(feature = "wake_trait", issue = "69912")]
101+
#[stable(feature = "wake_trait", since = "1.51.0")]
50102
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
51103
fn from(waker: Arc<W>) -> RawWaker {
52104
raw_waker(waker)

library/std/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,6 @@
329329
#![feature(unwind_attributes)]
330330
#![feature(vec_into_raw_parts)]
331331
#![feature(vec_spare_capacity)]
332-
#![feature(wake_trait)]
333332
// NB: the above list is sorted to minimize merge conflicts.
334333
#![default_lib_allocator]
335334

@@ -508,7 +507,7 @@ pub mod task {
508507
pub use core::task::*;
509508

510509
#[doc(inline)]
511-
#[unstable(feature = "wake_trait", issue = "69912")]
510+
#[stable(feature = "wake_trait", since = "1.51.0")]
512511
pub use alloc::task::*;
513512
}
514513

src/test/ui/async-await/issue-73137.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
// edition:2018
55

66
#![allow(dead_code)]
7-
#![feature(wake_trait)]
87
use std::future::Future;
98
use std::task::{Waker, Wake, Context};
109
use std::sync::Arc;

0 commit comments

Comments
 (0)