diff --git a/tokio-executor/CHANGELOG.md b/tokio-executor/CHANGELOG.md index 02dc5869e..328085b0d 100644 --- a/tokio-executor/CHANGELOG.md +++ b/tokio-executor/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.1.9 (November 27, 2019) + +### Added +- Add `executor::set_default` which behaves like `with_default` but returns a + drop guard (#1725). + # 0.1.8 (June 2, 2019) ### Added diff --git a/tokio-executor/Cargo.toml b/tokio-executor/Cargo.toml index 887396040..465bae8d6 100644 --- a/tokio-executor/Cargo.toml +++ b/tokio-executor/Cargo.toml @@ -8,8 +8,8 @@ name = "tokio-executor" # - README.md # - Update CHANGELOG.md. # - Create "v0.1.x" git tag. -version = "0.1.8" -documentation = "https://docs.rs/tokio-executor/0.1.7/tokio_executor" +version = "0.1.9" +documentation = "https://docs.rs/tokio-executor/0.1.9/tokio_executor" repository = "https://github.com/tokio-rs/tokio" homepage = "https://github.com/tokio-rs/tokio" license = "MIT" diff --git a/tokio-executor/README.md b/tokio-executor/README.md index 2eee44ce0..1a996107a 100644 --- a/tokio-executor/README.md +++ b/tokio-executor/README.md @@ -2,7 +2,7 @@ Task execution related traits and utilities. -[Documentation](https://docs.rs/tokio-executor/0.1.8/tokio_executor) +[Documentation](https://docs.rs/tokio-executor/0.1.9/tokio_executor) ## Overview @@ -31,10 +31,10 @@ executor, including: * [`Park`] abstracts over blocking and unblocking the current thread. -[`Executor`]: https://docs.rs/tokio-executor/0.1.8/tokio_executor/trait.Executor.html -[`enter`]: https://docs.rs/tokio-executor/0.1.8/tokio_executor/fn.enter.html -[`DefaultExecutor`]: https://docs.rs/tokio-executor/0.1.8/tokio_executor/struct.DefaultExecutor.html -[`Park`]: https://docs.rs/tokio-executor/0.1.8/tokio_executor/park/trait.Park.html +[`Executor`]: https://docs.rs/tokio-executor/0.1.9/tokio_executor/trait.Executor.html +[`enter`]: https://docs.rs/tokio-executor/0.1.9/tokio_executor/fn.enter.html +[`DefaultExecutor`]: https://docs.rs/tokio-executor/0.1.9/tokio_executor/struct.DefaultExecutor.html +[`Park`]: https://docs.rs/tokio-executor/0.1.9/tokio_executor/park/trait.Park.html ## License diff --git a/tokio-executor/src/global.rs b/tokio-executor/src/global.rs index 0e5c47740..501227608 100644 --- a/tokio-executor/src/global.rs +++ b/tokio-executor/src/global.rs @@ -3,7 +3,6 @@ use super::{Enter, Executor, SpawnError}; use futures::{future, Future}; use std::cell::Cell; -use std::marker::PhantomData; /// Executes futures on the default executor for the current execution context. /// @@ -23,8 +22,8 @@ pub struct DefaultExecutor { /// Ensures that the executor is removed from the thread-local context /// when leaving the scope. This handles cases that involve panicking. #[derive(Debug)] -pub struct DefaultGuard<'a> { - _lifetime: PhantomData<&'a ()>, +pub struct DefaultGuard { + _p: (), } impl DefaultExecutor { @@ -183,20 +182,11 @@ where T: Executor, F: FnOnce(&mut Enter) -> R, { - let _guard = set_default(executor); - f(enter) -} + unsafe fn hide_lt<'a>(p: *mut (dyn Executor + 'a)) -> *mut (dyn Executor + 'static) { + use std::mem; + mem::transmute(p) + } -/// Sets `executor` as the default executor, returning a guard that unsets it when -/// dropped. -/// -/// # Panics -/// -/// This function panics if there already is a default executor set. -pub fn set_default(executor: &mut T) -> DefaultGuard<'_> -where - T: Executor, -{ EXECUTOR.with(|cell| { match cell.get() { State::Ready(_) | State::Active => { @@ -205,6 +195,18 @@ where _ => {} } + // Ensure that the executor is removed from the thread-local context + // when leaving the scope. This handles cases that involve panicking. + struct Reset<'a>(&'a Cell); + + impl<'a> Drop for Reset<'a> { + fn drop(&mut self) { + self.0.set(State::Empty); + } + } + + let _reset = Reset(cell); + // While scary, this is safe. The function takes a // `&mut Executor`, which guarantees that the reference lives for the // duration of `with_default`. @@ -215,22 +217,50 @@ where let executor = unsafe { hide_lt(executor as &mut _ as *mut _) }; cell.set(State::Ready(executor)); + + f(enter) + }) +} + +/// Sets `executor` as the default executor, returning a guard that unsets it when +/// dropped. +/// +/// # Panics +/// +/// This function panics if there already is a default executor set. +pub fn set_default(executor: T) -> DefaultGuard +where + T: Executor + 'static, +{ + EXECUTOR.with(|cell| { + match cell.get() { + State::Ready(_) | State::Active => { + panic!("default executor already set for execution context") + } + _ => {} + } + + // Ensure that the executor will outlive the call to set_default, even + // if the drop guard is never dropped due to calls to `mem::forget` or + // similar. + let executor = Box::new(executor); + + cell.set(State::Ready(Box::into_raw(executor))); }); - DefaultGuard { - _lifetime: PhantomData, - } + DefaultGuard { _p: () } } -unsafe fn hide_lt<'a>(p: *mut (dyn Executor + 'a)) -> *mut (dyn Executor + 'static) { - use std::mem; - mem::transmute(p) -} - -impl<'a> Drop for DefaultGuard<'a> { +impl Drop for DefaultGuard { fn drop(&mut self) { let _ = EXECUTOR.try_with(|cell| { - cell.set(State::Empty); + if let State::Ready(prev) = cell.replace(State::Empty) { + // drop the previous executor. + unsafe { + let prev = Box::from_raw(prev); + drop(prev); + }; + } }); } } diff --git a/tokio-executor/src/lib.rs b/tokio-executor/src/lib.rs index 9abdf91c9..67aa4895f 100644 --- a/tokio-executor/src/lib.rs +++ b/tokio-executor/src/lib.rs @@ -1,5 +1,5 @@ #![deny(missing_docs, missing_debug_implementations)] -#![doc(html_root_url = "https://docs.rs/tokio-executor/0.1.8")] +#![doc(html_root_url = "https://docs.rs/tokio-executor/0.1.9")] //! Task execution related traits and utilities. //! diff --git a/tokio-reactor/CHANGELOG.md b/tokio-reactor/CHANGELOG.md index 15b2f8ec7..52ff17f36 100644 --- a/tokio-reactor/CHANGELOG.md +++ b/tokio-reactor/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.1.11 (November 27, 2019) + +### Added +- `set_default`, which functions like `with_default` but returns a drop + guard (#1725) + # 0.1.10 (September 25, 2019) ### Changed diff --git a/tokio-reactor/Cargo.toml b/tokio-reactor/Cargo.toml index 9896b9eb1..028493ed1 100644 --- a/tokio-reactor/Cargo.toml +++ b/tokio-reactor/Cargo.toml @@ -8,13 +8,13 @@ name = "tokio-reactor" # - README.md # - Update CHANGELOG.md. # - Create "v0.1.x" git tag. -version = "0.1.10" +version = "0.1.11" authors = ["Carl Lerche "] license = "MIT" readme = "README.md" repository = "https://github.com/tokio-rs/tokio" homepage = "https://tokio.rs" -documentation = "https://docs.rs/tokio-reactor/0.1.10/tokio_reactor" +documentation = "https://docs.rs/tokio-reactor/0.1.11/tokio_reactor" description = """ Event loop that drives Tokio I/O resources. """ diff --git a/tokio-reactor/README.md b/tokio-reactor/README.md index 1b8d0c046..f4041d6a6 100644 --- a/tokio-reactor/README.md +++ b/tokio-reactor/README.md @@ -2,7 +2,7 @@ Event loop that drives Tokio I/O resources. -[Documentation](https://docs.rs/tokio-reactor/0.1.10/tokio_reactor) +[Documentation](https://docs.rs/tokio-reactor/0.1.11/tokio_reactor) ## Overview @@ -25,10 +25,10 @@ are building a custom I/O resource. [`mio`]: http://github.com/carllerche/mio [`futures`]: http://github.com/rust-lang-nursery/futures-rs -[`Reactor`]: https://docs.rs/tokio-reactor/0.1.10/tokio_reactor/struct.Reactor.html -[`Handle`]: https://docs.rs/tokio-reactor/0.1.10/tokio_reactor/struct.Handle.html -[`Registration`]: https://docs.rs/tokio-reactor/0.1.10/tokio_reactor/struct.Registration.html -[`PollEvented`]: https://docs.rs/tokio-reactor/0.1.10/tokio_reactor/struct.PollEvented.html +[`Reactor`]: https://docs.rs/tokio-reactor/0.1.11/tokio_reactor/struct.Reactor.html +[`Handle`]: https://docs.rs/tokio-reactor/0.1.11/tokio_reactor/struct.Handle.html +[`Registration`]: https://docs.rs/tokio-reactor/0.1.11/tokio_reactor/struct.Registration.html +[`PollEvented`]: https://docs.rs/tokio-reactor/0.1.11/tokio_reactor/struct.PollEvented.html [`tokio`]: ../ ## License diff --git a/tokio-reactor/src/lib.rs b/tokio-reactor/src/lib.rs index c28a7ae6b..50005d9ff 100644 --- a/tokio-reactor/src/lib.rs +++ b/tokio-reactor/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url = "https://docs.rs/tokio-reactor/0.1.10")] +#![doc(html_root_url = "https://docs.rs/tokio-reactor/0.1.11")] #![deny(missing_docs, missing_debug_implementations)] //! Event loop that drives Tokio I/O resources. @@ -68,7 +68,6 @@ use tokio_sync::task::AtomicTask; use std::cell::RefCell; use std::error::Error; use std::io; -use std::marker::PhantomData; use std::mem; #[cfg(all(unix, not(target_os = "fuchsia")))] use std::os::unix::io::{AsRawFd, RawFd}; @@ -137,8 +136,8 @@ pub type SetDefaultError = SetFallbackError; /// Ensure that the default reactor is removed from the thread-local context /// when leaving the scope. This handles cases that involve panicking. #[derive(Debug)] -pub struct DefaultGuard<'a> { - _lifetime: PhantomData<&'a ()>, +pub struct DefaultGuard { + _p: (), } #[test] @@ -217,7 +216,7 @@ where /// # Panics /// /// This function panics if there already is a default reactor set. -pub fn set_default(handle: &Handle) -> DefaultGuard<'_> { +pub fn set_default(handle: &Handle) -> DefaultGuard { CURRENT_REACTOR.with(|current| { let mut current = current.borrow_mut(); @@ -236,9 +235,7 @@ pub fn set_default(handle: &Handle) -> DefaultGuard<'_> { *current = Some(handle.clone()); }); - DefaultGuard { - _lifetime: PhantomData, - } + DefaultGuard { _p: () } } impl Reactor { @@ -746,7 +743,7 @@ impl Direction { } } -impl<'a> Drop for DefaultGuard<'a> { +impl Drop for DefaultGuard { fn drop(&mut self) { let _ = CURRENT_REACTOR.try_with(|current| { let mut current = current.borrow_mut(); diff --git a/tokio-timer/CHANGELOG.md b/tokio-timer/CHANGELOG.md index ca5d10694..ce7d7bf4f 100644 --- a/tokio-timer/CHANGELOG.md +++ b/tokio-timer/CHANGELOG.md @@ -1,3 +1,11 @@ +# 0.2.12 (November 27, 2019) + +### Added +- `timer::set_default`, which functions like `timer::with_default`, but + returns a drop guard (#1725). +- `clock::set_default`, which functions like `clock::with_default`, but + returns a drop guard (#1725). + # 0.2.11 (May 14, 2019) ### Added diff --git a/tokio-timer/Cargo.toml b/tokio-timer/Cargo.toml index 3ee921633..6330299b1 100644 --- a/tokio-timer/Cargo.toml +++ b/tokio-timer/Cargo.toml @@ -8,11 +8,11 @@ name = "tokio-timer" # - README.md # - Update CHANGELOG.md. # - Create "v0.2.x" git tag. -version = "0.2.11" +version = "0.2.12" authors = ["Carl Lerche "] license = "MIT" readme = "README.md" -documentation = "https://docs.rs/tokio-timer/0.2.11/tokio_timer" +documentation = "https://docs.rs/tokio-timer/0.2.12/tokio_timer" repository = "https://github.com/tokio-rs/tokio" homepage = "https://github.com/tokio-rs/tokio" description = """ diff --git a/tokio-timer/README.md b/tokio-timer/README.md index b4908eedd..7f894a195 100644 --- a/tokio-timer/README.md +++ b/tokio-timer/README.md @@ -2,7 +2,7 @@ Timer facilities for Tokio -[Documentation](https://docs.rs/tokio-timer/0.2.11/tokio_timer/) +[Documentation](https://docs.rs/tokio-timer/0.2.12/tokio_timer/) ## Overview diff --git a/tokio-timer/src/clock/clock.rs b/tokio-timer/src/clock/clock.rs index e65d668e4..2920e2817 100644 --- a/tokio-timer/src/clock/clock.rs +++ b/tokio-timer/src/clock/clock.rs @@ -3,9 +3,8 @@ use timer; use tokio_executor::Enter; -use std::cell::Cell; +use std::cell::RefCell; use std::fmt; -use std::marker::PhantomData; use std::sync::Arc; use std::time::Instant; @@ -23,13 +22,13 @@ pub struct Clock { /// A guard that resets the current `Clock` to `None` when dropped. #[derive(Debug)] -pub struct DefaultGuard<'a> { - _lifetime: PhantomData<&'a ()>, +pub struct DefaultGuard { + _p: (), } thread_local! { /// Thread-local tracking the current clock - static CLOCK: Cell> = Cell::new(None) + static CLOCK: RefCell> = RefCell::new(None) } /// Returns an `Instant` corresponding to "now". @@ -50,8 +49,8 @@ thread_local! { /// let now = clock::now(); /// ``` pub fn now() -> Instant { - CLOCK.with(|current| match current.get() { - Some(ptr) => unsafe { (*ptr).now() }, + CLOCK.with(|current| match current.borrow().as_ref() { + Some(c) => c.now(), None => Instant::now(), }) } @@ -60,8 +59,8 @@ impl Clock { /// Return a new `Clock` instance that uses the current execution context's /// source of time. pub fn new() -> Clock { - CLOCK.with(|current| match current.get() { - Some(ptr) => unsafe { (*ptr).clone() }, + CLOCK.with(|current| match current.borrow().as_ref() { + Some(c) => c.clone(), None => Clock::system(), }) } @@ -131,25 +130,21 @@ where /// # Panics /// /// This function panics if there already is a default clock set. -pub fn set_default(clock: &Clock) -> DefaultGuard<'_> { +pub fn set_default(clock: &Clock) -> DefaultGuard { CLOCK.with(|cell| { assert!( - cell.get().is_none(), + cell.borrow().is_none(), "default clock already set for execution context" ); - cell.set(Some(clock as *const Clock)); + *cell.borrow_mut() = Some(clock.clone()); - DefaultGuard { - _lifetime: PhantomData, - } + DefaultGuard { _p: () } }) } -impl<'a> Drop for DefaultGuard<'a> { +impl Drop for DefaultGuard { fn drop(&mut self) { - let _ = CLOCK.try_with(|cell| { - cell.set(None); - }); + let _ = CLOCK.try_with(|cell| cell.borrow_mut().take()); } } diff --git a/tokio-timer/src/lib.rs b/tokio-timer/src/lib.rs index 49aca370f..721fc06c6 100644 --- a/tokio-timer/src/lib.rs +++ b/tokio-timer/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url = "https://docs.rs/tokio-timer/0.2.11")] +#![doc(html_root_url = "https://docs.rs/tokio-timer/0.2.12")] #![deny(missing_docs, missing_debug_implementations)] //! Utilities for tracking time. diff --git a/tokio-timer/src/timer/handle.rs b/tokio-timer/src/timer/handle.rs index 3129ec9bf..4c444d8a6 100644 --- a/tokio-timer/src/timer/handle.rs +++ b/tokio-timer/src/timer/handle.rs @@ -5,7 +5,6 @@ use tokio_executor::Enter; use std::cell::RefCell; use std::fmt; -use std::marker::PhantomData; use std::sync::{Arc, Weak}; use std::time::{Duration, Instant}; @@ -47,8 +46,8 @@ pub(crate) struct HandlePriv { /// A guard that resets the current timer to `None` when dropped. #[derive(Debug)] -pub struct DefaultGuard<'a> { - _lifetime: PhantomData<&'a ()>, +pub struct DefaultGuard { + _p: (), } thread_local! { @@ -80,7 +79,7 @@ where /// # Panics /// /// This function panics if there already is a default timer set. -pub fn set_default(handle: &Handle) -> DefaultGuard<'_> { +pub fn set_default(handle: &Handle) -> DefaultGuard { CURRENT_TIMER.with(|current| { let mut current = current.borrow_mut(); @@ -96,9 +95,7 @@ pub fn set_default(handle: &Handle) -> DefaultGuard<'_> { *current = Some(handle.clone()); }); - DefaultGuard { - _lifetime: PhantomData, - } + DefaultGuard { _p: () } } impl Handle { @@ -194,7 +191,7 @@ impl fmt::Debug for HandlePriv { } } -impl<'a> Drop for DefaultGuard<'a> { +impl Drop for DefaultGuard { fn drop(&mut self) { let _ = CURRENT_TIMER.try_with(|current| { let mut current = current.borrow_mut();