diff options
| author | bors <bors@rust-lang.org> | 2023-06-07 06:04:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-06-07 06:04:32 +0000 |
| commit | 10b7e468f3cc263b8df8ff0212d0911ed5a3c090 (patch) | |
| tree | 4638537e2fa54b9e0954a04c081528e5dbb04abb | |
| parent | b3dd578767299e6bcb617fbb28724fe32b31cf3b (diff) | |
| parent | 1818ed7cfe8182c14cf05265d7af21ebd987b71e (diff) | |
| download | rust-10b7e468f3cc263b8df8ff0212d0911ed5a3c090.tar.gz rust-10b7e468f3cc263b8df8ff0212d0911ed5a3c090.zip | |
Auto merge of #96875 - SabrinaJewson:noop-waker, r=m-ou-se
Add `task::Waker::noop` I have found myself reimplementing this function many times when I need a `Context` but don't have a runtime or `futures` to hand. Prior art: [`futures::task::noop_waker`](https://docs.rs/futures/0.3/futures/task/fn.noop_waker.html) and [`futures::task::noop_waker_ref`](https://docs.rs/futures/0.3/futures/task/fn.noop_waker_ref.html) Tracking issue: https://github.com/rust-lang/rust/issues/98286 Unresolved questions: 1. Should we also add `RawWaker::noop()`? (I don't think so, I can't think of a use case for it) 2. Should we also add `Context::noop()`? Depending on the future direction `Context` goes a "noop context" might not even make sense in future. 3. Should it be an associated constant instead? That would allow for `let cx = &mut Context::from_waker(&Waker::NOOP);` to work on one line which is pretty nice. I don't really know what the guideline is here. r? rust-lang/libs-api `@rustbot` label +T-libs-api -T-libs
| -rw-r--r-- | library/core/src/task/wake.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 7043ab5ff2b..b63fd5c9095 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -2,6 +2,7 @@ use crate::fmt; use crate::marker::{PhantomData, Unpin}; +use crate::ptr; /// A `RawWaker` allows the implementor of a task executor to create a [`Waker`] /// which provides customized wakeup behavior. @@ -322,6 +323,45 @@ impl Waker { Waker { waker } } + /// Creates a new `Waker` that does nothing when `wake` is called. + /// + /// This is mostly useful for writing tests that need a [`Context`] to poll + /// some futures, but are not expecting those futures to wake the waker or + /// do not need to do anything specific if it happens. + /// + /// # Examples + /// + /// ``` + /// #![feature(noop_waker)] + /// + /// use std::future::Future; + /// use std::task; + /// + /// let waker = task::Waker::noop(); + /// let mut cx = task::Context::from_waker(&waker); + /// + /// let mut future = Box::pin(async { 10 }); + /// assert_eq!(future.as_mut().poll(&mut cx), task::Poll::Ready(10)); + /// ``` + #[inline] + #[must_use] + #[unstable(feature = "noop_waker", issue = "98286")] + pub const fn noop() -> Waker { + const VTABLE: RawWakerVTable = RawWakerVTable::new( + // Cloning just returns a new no-op raw waker + |_| RAW, + // `wake` does nothing + |_| {}, + // `wake_by_ref` does nothing + |_| {}, + // Dropping does nothing as we don't allocate anything + |_| {}, + ); + const RAW: RawWaker = RawWaker::new(ptr::null(), &VTABLE); + + Waker { waker: RAW } + } + /// Get a reference to the underlying [`RawWaker`]. #[inline] #[must_use] |
