diff --git a/Cargo.toml b/Cargo.toml index 4fca8f2..b3c2dd7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ exclude = ["/.*"] [features] default = ["std"] -std = ["alloc", "fastrand", "futures-io", "parking", "memchr", "waker-fn"] +std = ["alloc", "fastrand", "futures-io", "memchr", "waker-fn"] alloc = [] [dependencies] @@ -29,7 +29,6 @@ fastrand = { version = "1.3.4", optional = true } futures-core = { version = "0.3.5", default-features = false } futures-io = { version = "0.3.5", optional = true } memchr = { version = "2.3.3", optional = true } -parking = { version = "2.0.0", optional = true } pin-project-lite = "0.2.0" waker-fn = { version = "1.0.0", optional = true } diff --git a/src/future.rs b/src/future.rs index b54fcee..f37f8e4 100644 --- a/src/future.rs +++ b/src/future.rs @@ -52,59 +52,32 @@ use core::task::{Context, Poll}; /// ``` #[cfg(feature = "std")] pub fn block_on(future: impl Future) -> T { - use std::cell::RefCell; use std::task::Waker; - use parking::Parker; use waker_fn::waker_fn; // Pin the future on the stack. crate::pin!(future); - // Creates a parker and an associated waker that unparks it. - fn parker_and_waker() -> (Parker, Waker) { - let parker = Parker::new(); - let unparker = parker.unparker(); - let waker = waker_fn(move || { - unparker.unpark(); - }); - (parker, waker) - } - thread_local! { + // Creates a cached waker that unparks the current thread it. // Cached parker and waker for efficiency. - static CACHE: RefCell<(Parker, Waker)> = RefCell::new(parker_and_waker()); + static CACHE: Waker = { + let thread = std::thread::current(); + waker_fn(move || thread.unpark()) + }; } CACHE.with(|cache| { - // Try grabbing the cached parker and waker. - match cache.try_borrow_mut() { - Ok(cache) => { - // Use the cached parker and waker. - let (parker, waker) = &*cache; - let cx = &mut Context::from_waker(waker); - - // Keep polling until the future is ready. - loop { - match future.as_mut().poll(cx) { - Poll::Ready(output) => return output, - Poll::Pending => parker.park(), - } - } - } - Err(_) => { - // Looks like this is a recursive `block_on()` call. - // Create a fresh parker and waker. - let (parker, waker) = parker_and_waker(); - let cx = &mut Context::from_waker(&waker); - - // Keep polling until the future is ready. - loop { - match future.as_mut().poll(cx) { - Poll::Ready(output) => return output, - Poll::Pending => parker.park(), - } - } + // Use the cached waker. + let waker = &*cache; + let cx = &mut Context::from_waker(waker); + + // Keep polling until the future is ready. + loop { + match future.as_mut().poll(cx) { + Poll::Ready(output) => return output, + Poll::Pending => std::thread::park(), } } })