From 232ed5feb0bc31cf6b548e9506dbedba201ec3ad Mon Sep 17 00:00:00 2001 From: KaiJewson Date: Sat, 6 Feb 2021 07:27:19 +0000 Subject: [PATCH 1/2] Avoid once_cell in static wakers --- futures-task/Cargo.toml | 3 +-- futures-task/src/noop_waker.rs | 21 +++++++++++---------- futures-test/Cargo.toml | 3 +-- futures-test/src/task/panic_waker.rs | 25 +++++++++++++------------ 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/futures-task/Cargo.toml b/futures-task/Cargo.toml index 3a8a67aa53..4a9d7eb44e 100644 --- a/futures-task/Cargo.toml +++ b/futures-task/Cargo.toml @@ -13,7 +13,7 @@ Tools for working with tasks. [features] default = ["std"] -std = ["alloc", "once_cell"] +std = ["alloc"] alloc = [] # Unstable features @@ -23,7 +23,6 @@ unstable = [] cfg-target-has-atomic = [] [dependencies] -once_cell = { version = "1.3.1", default-features = false, features = ["std"], optional = true } [dev-dependencies] futures = { path = "../futures" } diff --git a/futures-task/src/noop_waker.rs b/futures-task/src/noop_waker.rs index 2a84bcd6f3..f76a8a2e95 100644 --- a/futures-task/src/noop_waker.rs +++ b/futures-task/src/noop_waker.rs @@ -1,9 +1,7 @@ //! Utilities for creating zero-cost wakers that don't do anything. -use core::task::{RawWaker, RawWakerVTable, Waker}; use core::ptr::null; -#[cfg(feature = "std")] -use once_cell::sync::Lazy; +use core::task::{RawWaker, RawWakerVTable, Waker}; unsafe fn noop_clone(_data: *const ()) -> RawWaker { noop_raw_waker() @@ -13,7 +11,7 @@ unsafe fn noop(_data: *const ()) {} const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop); -fn noop_raw_waker() -> RawWaker { +const fn noop_raw_waker() -> RawWaker { RawWaker::new(null(), &NOOP_WAKER_VTABLE) } @@ -29,9 +27,8 @@ fn noop_raw_waker() -> RawWaker { /// ``` #[inline] pub fn noop_waker() -> Waker { - unsafe { - Waker::from_raw(noop_raw_waker()) - } + // FIXME: Since 1.46.0 we can use transmute in consts, allowing this function to be const. + unsafe { Waker::from_raw(noop_raw_waker()) } } /// Get a static reference to a [`Waker`] which @@ -45,10 +42,14 @@ pub fn noop_waker() -> Waker { /// waker.wake_by_ref(); /// ``` #[inline] -#[cfg(feature = "std")] pub fn noop_waker_ref() -> &'static Waker { - static NOOP_WAKER_INSTANCE: Lazy = Lazy::new(noop_waker); - &*NOOP_WAKER_INSTANCE + struct SyncRawWaker(RawWaker); + unsafe impl Sync for SyncRawWaker {} + + static NOOP_WAKER_INSTANCE: SyncRawWaker = SyncRawWaker(noop_raw_waker()); + + // SAFETY: `Waker` is #[repr(transparent)] over its `RawWaker`. + unsafe { &*(&NOOP_WAKER_INSTANCE.0 as *const RawWaker as *const Waker) } } #[cfg(test)] diff --git a/futures-test/Cargo.toml b/futures-test/Cargo.toml index d0fd5446ec..d48644574b 100644 --- a/futures-test/Cargo.toml +++ b/futures-test/Cargo.toml @@ -19,7 +19,6 @@ futures-util = { version = "0.3.12", path = "../futures-util", default-features futures-executor = { version = "0.3.12", path = "../futures-executor", default-features = false } futures-sink = { version = "0.3.12", path = "../futures-sink", default-features = false } pin-utils = { version = "0.1.0", default-features = false } -once_cell = { version = "1.3.1", default-features = false, features = ["std"], optional = true } pin-project = "1.0.1" [dev-dependencies] @@ -27,7 +26,7 @@ futures = { path = "../futures", default-features = false, features = ["std", "e [features] default = ["std"] -std = ["futures-core/std", "futures-task/std", "futures-io/std", "futures-util/std", "futures-util/io", "futures-executor/std", "once_cell"] +std = ["futures-core/std", "futures-task/std", "futures-io/std", "futures-util/std", "futures-util/io", "futures-executor/std"] [package.metadata.docs.rs] all-features = true diff --git a/futures-test/src/task/panic_waker.rs b/futures-test/src/task/panic_waker.rs index d38d215958..38e2443156 100644 --- a/futures-test/src/task/panic_waker.rs +++ b/futures-test/src/task/panic_waker.rs @@ -1,6 +1,5 @@ -use futures_core::task::{Waker, RawWaker, RawWakerVTable}; use core::ptr::null; -use once_cell::sync::Lazy; +use futures_core::task::{RawWaker, RawWakerVTable, Waker}; unsafe fn clone_panic_waker(_data: *const ()) -> RawWaker { raw_panic_waker() @@ -9,19 +8,15 @@ unsafe fn clone_panic_waker(_data: *const ()) -> RawWaker { unsafe fn noop(_data: *const ()) {} unsafe fn wake_panic(_data: *const ()) { - if ! std::thread::panicking() { + if !std::thread::panicking() { panic!("should not be woken"); } } -const PANIC_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new( - clone_panic_waker, - wake_panic, - wake_panic, - noop, -); +const PANIC_WAKER_VTABLE: RawWakerVTable = + RawWakerVTable::new(clone_panic_waker, wake_panic, wake_panic, noop); -fn raw_panic_waker() -> RawWaker { +const fn raw_panic_waker() -> RawWaker { RawWaker::new(null(), &PANIC_WAKER_VTABLE) } @@ -38,6 +33,7 @@ fn raw_panic_waker() -> RawWaker { /// waker.wake(); // Will panic /// ``` pub fn panic_waker() -> Waker { + // FIXME: Since 1.46.0 we can use transmute in consts, allowing this function to be const. unsafe { Waker::from_raw(raw_panic_waker()) } } @@ -54,8 +50,13 @@ pub fn panic_waker() -> Waker { /// waker.wake_by_ref(); // Will panic /// ``` pub fn panic_waker_ref() -> &'static Waker { - static PANIC_WAKER_INSTANCE: Lazy = Lazy::new(panic_waker); - &*PANIC_WAKER_INSTANCE + struct SyncRawWaker(RawWaker); + unsafe impl Sync for SyncRawWaker {} + + static PANIC_WAKER_INSTANCE: SyncRawWaker = SyncRawWaker(raw_panic_waker()); + + // SAFETY: `Waker` is #[repr(transparent)] over its `RawWaker`. + unsafe { &*(&PANIC_WAKER_INSTANCE.0 as *const RawWaker as *const Waker) } } #[cfg(test)] From 4c09f82a1e60c2e44b9b467e05e0a6b086c061be Mon Sep 17 00:00:00 2001 From: KaiJewson Date: Sat, 6 Feb 2021 07:40:17 +0000 Subject: [PATCH 2/2] Always export noop_waker_ref --- futures-task/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/futures-task/src/lib.rs b/futures-task/src/lib.rs index e2231a587b..5505e3ad49 100644 --- a/futures-task/src/lib.rs +++ b/futures-task/src/lib.rs @@ -48,7 +48,6 @@ pub use crate::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj}; mod noop_waker; pub use crate::noop_waker::noop_waker; -#[cfg(feature = "std")] pub use crate::noop_waker::noop_waker_ref; #[doc(no_inline)]