Skip to content

Commit

Permalink
Avoid once_cell in static wakers (#2332)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kai Jewson committed Feb 6, 2021
1 parent 1803948 commit ddbf522
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 27 deletions.
3 changes: 1 addition & 2 deletions futures-task/Cargo.toml
Expand Up @@ -13,7 +13,7 @@ Tools for working with tasks.

[features]
default = ["std"]
std = ["alloc", "once_cell"]
std = ["alloc"]
alloc = []

# Unstable features
Expand All @@ -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" }
Expand Down
1 change: 0 additions & 1 deletion futures-task/src/lib.rs
Expand Up @@ -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)]
Expand Down
21 changes: 11 additions & 10 deletions 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()
Expand All @@ -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)
}

Expand All @@ -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
Expand All @@ -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<Waker> = 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)]
Expand Down
3 changes: 1 addition & 2 deletions futures-test/Cargo.toml
Expand Up @@ -19,15 +19,14 @@ 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]
futures = { path = "../futures", default-features = false, features = ["std", "executor"] }

[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
25 changes: 13 additions & 12 deletions 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()
Expand All @@ -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)
}

Expand All @@ -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()) }
}

Expand All @@ -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<Waker> = 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)]
Expand Down

0 comments on commit ddbf522

Please sign in to comment.