Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid once_cell in static wakers #2332

Merged
merged 2 commits into from Feb 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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