From b8cee1a60ad99ef28ec494ae4230e2ef4399fcf9 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Mon, 21 Oct 2019 16:45:13 -0700 Subject: [PATCH] timer: move `tokio-timer` into `tokio` crate (#1674) A step towards collapsing Tokio sub crates into a single `tokio` crate (#1318). The `timer` implementation is now provided by the main `tokio` crate. The `timer` functionality may still be excluded from the build by skipping the `timer` feature flag. --- Cargo.toml | 1 - azure-pipelines.yml | 2 - ci/patch.toml | 1 - tokio-test/Cargo.toml | 1 - tokio-test/src/clock.rs | 12 +- tokio-test/src/io.rs | 46 +-- tokio-test/tests/block_on.rs | 5 +- tokio-test/tests/clock.rs | 34 +-- tokio-timer/CHANGELOG.md | 102 ------- tokio-timer/Cargo.toml | 46 --- tokio-timer/LICENSE | 25 -- tokio-timer/README.md | 13 - tokio-timer/src/lib.rs | 105 ------- tokio-timer/tests/support/mod.rs | 265 ------------------ tokio/Cargo.toml | 7 +- tokio/src/clock.rs | 7 +- tokio/src/future.rs | 2 +- tokio/src/runtime/current_thread/builder.rs | 8 +- tokio/src/runtime/current_thread/runtime.rs | 4 +- tokio/src/runtime/mod.rs | 3 +- tokio/src/runtime/threadpool/builder.rs | 8 +- tokio/src/runtime/threadpool/mod.rs | 3 +- tokio/src/stream.rs | 2 +- .../src => tokio/src/timer}/atomic.rs | 0 .../src => tokio/src/timer}/clock/mod.rs | 10 +- .../src => tokio/src/timer}/clock/now.rs | 0 .../src => tokio/src/timer}/deadline.rs | 0 {tokio-timer/src => tokio/src/timer}/delay.rs | 5 +- .../src => tokio/src/timer}/delay_queue.rs | 30 +- {tokio-timer/src => tokio/src/timer}/error.rs | 0 .../src => tokio/src/timer}/interval.rs | 7 +- tokio/src/{timer.rs => timer/mod.rs} | 75 ++++- .../src => tokio/src/timer}/throttle.rs | 3 +- .../src => tokio/src/timer}/timeout.rs | 7 +- .../src/timer}/timer/atomic_stack.rs | 3 +- .../src => tokio/src/timer}/timer/entry.rs | 10 +- .../src => tokio/src/timer}/timer/handle.rs | 7 +- .../src => tokio/src/timer}/timer/mod.rs | 74 +++-- .../src => tokio/src/timer}/timer/now.rs | 0 .../src/timer}/timer/registration.rs | 6 +- .../src => tokio/src/timer}/timer/stack.rs | 5 +- .../src => tokio/src/timer}/wheel/level.rs | 3 +- .../src => tokio/src/timer}/wheel/mod.rs | 4 +- .../src => tokio/src/timer}/wheel/stack.rs | 0 tokio/tests/clock.rs | 6 +- .../clock.rs => tokio/tests/timer_clock.rs | 5 +- .../delay.rs => tokio/tests/timer_delay.rs | 8 +- .../hammer.rs => tokio/tests/timer_hammer.rs | 3 +- .../tests/timer_interval.rs | 2 +- .../queue.rs => tokio/tests/timer_queue.rs | 2 +- tokio/tests/{timer.rs => timer_rt.rs} | 1 - .../tests/timer_throttle.rs | 5 +- .../tests/timer_timeout.rs | 4 +- 53 files changed, 216 insertions(+), 771 deletions(-) delete mode 100644 tokio-timer/CHANGELOG.md delete mode 100644 tokio-timer/Cargo.toml delete mode 100644 tokio-timer/LICENSE delete mode 100644 tokio-timer/README.md delete mode 100644 tokio-timer/src/lib.rs delete mode 100644 tokio-timer/tests/support/mod.rs rename {tokio-timer/src => tokio/src/timer}/atomic.rs (100%) rename {tokio-timer/src => tokio/src/timer}/clock/mod.rs (96%) rename {tokio-timer/src => tokio/src/timer}/clock/now.rs (100%) rename {tokio-timer/src => tokio/src/timer}/deadline.rs (100%) rename {tokio-timer/src => tokio/src/timer}/delay.rs (96%) rename {tokio-timer/src => tokio/src/timer}/delay_queue.rs (97%) rename {tokio-timer/src => tokio/src/timer}/error.rs (100%) rename {tokio-timer/src => tokio/src/timer}/interval.rs (93%) rename tokio/src/{timer.rs => timer/mod.rs} (59%) rename {tokio-timer/src => tokio/src/timer}/throttle.rs (98%) rename {tokio-timer/src => tokio/src/timer}/timeout.rs (98%) rename {tokio-timer/src => tokio/src/timer}/timer/atomic_stack.rs (99%) rename {tokio-timer/src => tokio/src/timer}/timer/entry.rs (99%) rename {tokio-timer/src => tokio/src/timer}/timer/handle.rs (98%) rename {tokio-timer/src => tokio/src/timer}/timer/mod.rs (92%) rename {tokio-timer/src => tokio/src/timer}/timer/now.rs (100%) rename {tokio-timer/src => tokio/src/timer}/timer/registration.rs (94%) rename {tokio-timer/src => tokio/src/timer}/timer/stack.rs (98%) rename {tokio-timer/src => tokio/src/timer}/wheel/level.rs (99%) rename {tokio-timer/src => tokio/src/timer}/wheel/mod.rs (100%) rename {tokio-timer/src => tokio/src/timer}/wheel/stack.rs (100%) rename tokio-timer/tests/clock.rs => tokio/tests/timer_clock.rs (93%) rename tokio-timer/tests/delay.rs => tokio/tests/timer_delay.rs (99%) rename tokio-timer/tests/hammer.rs => tokio/tests/timer_hammer.rs (99%) rename tokio-timer/tests/interval.rs => tokio/tests/timer_interval.rs (98%) rename tokio-timer/tests/queue.rs => tokio/tests/timer_queue.rs (99%) rename tokio/tests/{timer.rs => timer_rt.rs} (98%) rename tokio-timer/tests/throttle.rs => tokio/tests/timer_throttle.rs (93%) rename tokio-timer/tests/timeout.rs => tokio/tests/timer_timeout.rs (98%) diff --git a/Cargo.toml b/Cargo.toml index 7333a8d58..5883131b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ members = [ "tokio-net", "tokio-sync", "tokio-test", - "tokio-timer", "tokio-tls", "build-tests", ] diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 374df5f6b..b943bfe61 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -70,8 +70,6 @@ jobs: tokio-sync: - async-traits tokio-macros: [] - tokio-timer: - - async-traits tokio-test: [] # Test compilation failure diff --git a/ci/patch.toml b/ci/patch.toml index 49a7252f6..e6dc91487 100644 --- a/ci/patch.toml +++ b/ci/patch.toml @@ -8,5 +8,4 @@ tokio-io = { path = "tokio-io" } tokio-macros = { path = "tokio-macros" } tokio-net = { path = "tokio-net" } tokio-sync = { path = "tokio-sync" } -tokio-timer = { path = "tokio-timer" } tokio-tls = { path = "tokio-tls" } diff --git a/tokio-test/Cargo.toml b/tokio-test/Cargo.toml index 2c5fbf4bf..ce9ece118 100644 --- a/tokio-test/Cargo.toml +++ b/tokio-test/Cargo.toml @@ -24,7 +24,6 @@ tokio = { version = "=0.2.0-alpha.6", path = "../tokio" } tokio-executor = { version = "=0.2.0-alpha.6", path = "../tokio-executor" } tokio-io = { version = "=0.2.0-alpha.6", path = "../tokio-io" } tokio-sync = { version = "=0.2.0-alpha.6", path = "../tokio-sync" } -tokio-timer = { version = "=0.3.0-alpha.6", path = "../tokio-timer" } futures-core-preview = "=0.3.0-alpha.19" pin-convert = "0.1.0" diff --git a/tokio-test/src/clock.rs b/tokio-test/src/clock.rs index ea4f04659..dd09a0095 100644 --- a/tokio-test/src/clock.rs +++ b/tokio-test/src/clock.rs @@ -1,11 +1,11 @@ -//! A mocked clock for use with `tokio_timer` based futures. +//! A mocked clock for use with `tokio::timer` based futures. //! //! # Example //! //! ``` //! use tokio::clock; +//! use tokio::timer::delay; //! use tokio_test::{assert_ready, assert_pending, task}; -//! use tokio_timer::delay; //! //! use std::time::Duration; //! @@ -22,9 +22,9 @@ //! }); //! ``` +use tokio::timer::clock::{Clock, Now}; +use tokio::timer::Timer; use tokio_executor::park::{Park, Unpark}; -use tokio_timer::clock::{Clock, Now}; -use tokio_timer::Timer; use std::marker::PhantomData; use std::rc::Rc; @@ -125,13 +125,13 @@ impl MockClock { where F: FnOnce(&mut Handle) -> R, { - ::tokio_timer::clock::with_default(&self.clock, || { + tokio::timer::clock::with_default(&self.clock, || { let park = self.time.mock_park(); let timer = Timer::new(park); let handle = timer.handle(); let time = self.time.clone(); - let _timer = ::tokio_timer::set_default(&handle); + let _timer = tokio::timer::set_default(&handle); let mut handle = Handle::new(timer, time); f(&mut handle) // lazy(|| Ok::<_, ()>(f(&mut handle))).wait().unwrap() diff --git a/tokio-test/src/io.rs b/tokio-test/src/io.rs index ffbb07c53..6610c1dbc 100644 --- a/tokio-test/src/io.rs +++ b/tokio-test/src/io.rs @@ -16,6 +16,11 @@ //! [`AsyncRead`]: tokio_io::AsyncRead //! [`AsyncWrite`]: tokio_io::AsyncWrite +use tokio::timer::{clock, timer, Delay}; +use tokio_io::{AsyncRead, AsyncWrite, Buf}; +use tokio_sync::mpsc; + +use futures_core::ready; use std::collections::VecDeque; use std::future::Future; use std::pin::Pin; @@ -23,11 +28,6 @@ use std::task::{self, Poll, Waker}; use std::time::{Duration, Instant}; use std::{cmp, io}; -use futures_core::ready; -use tokio_io::{AsyncRead, AsyncWrite, Buf}; -use tokio_sync::mpsc; -use tokio_timer::{clock, timer, Delay}; - /// An I/O object that follows a predefined script. /// /// This value is created by `Builder` and implements `AsyncRead` + `AsyncWrite`. It @@ -268,42 +268,6 @@ impl Inner { } } -/* -impl io::Read for Mock { - fn read(&mut self, dst: &mut [u8]) -> io::Result { - if self.is_async() { - tokio::async_read(self, dst) - } else { - self.sync_read(dst) - } - } -} - -impl io::Write for Mock { - fn write(&mut self, src: &[u8]) -> io::Result { - if self.is_async() { - tokio::async_write(self, src) - } else { - self.sync_write(src) - } - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} -*/ - -/* -use self::futures::{Future, Stream, Poll, Async}; -use self::futures::sync::mpsc; -use self::futures::task::{self, Task}; -use self::tokio_io::{AsyncRead, AsyncWrite}; -use self::tokio_timer::{Timer, Sleep}; - -use std::io; -*/ - // ===== impl Inner ===== impl Mock { diff --git a/tokio-test/tests/block_on.rs b/tokio-test/tests/block_on.rs index 9b4959e9a..6d5f481a4 100644 --- a/tokio-test/tests/block_on.rs +++ b/tokio-test/tests/block_on.rs @@ -1,8 +1,9 @@ #![warn(rust_2018_idioms)] -use std::time::{Duration, Instant}; +use tokio::timer::delay; use tokio_test::block_on; -use tokio_timer::delay; + +use std::time::{Duration, Instant}; #[test] fn async_block() { diff --git a/tokio-test/tests/clock.rs b/tokio-test/tests/clock.rs index 344c599b6..abb61e232 100644 --- a/tokio-test/tests/clock.rs +++ b/tokio-test/tests/clock.rs @@ -1,12 +1,11 @@ -#![cfg(feature = "broken")] #![warn(rust_2018_idioms)] -use futures::Future; -use std::time::{Duration, Instant}; +use tokio::timer::delay; use tokio_test::clock::MockClock; -use tokio_test::task::MockTask; -use tokio_test::{assert_not_ready, assert_ready}; -use tokio_timer::delay; +use tokio_test::task; +use tokio_test::{assert_pending, assert_ready}; + +use std::time::{Duration, Instant}; #[test] fn clock() { @@ -14,30 +13,13 @@ fn clock() { mock.enter(|handle| { let deadline = Instant::now() + Duration::from_secs(1); - let mut delay = delay(deadline); + let mut delay = task::spawn(delay(deadline)); - assert_not_ready!(delay.poll()); + assert_pending!(delay.poll()); handle.advance(Duration::from_secs(2)); - assert_ready!(delay.poll()); - }); -} - -#[test] -fn notify() { - let deadline = Instant::now() + Duration::from_secs(1); - let mut mock = MockClock::new(); - let mut task = MockTask::new(); - - mock.enter(|handle| { - let mut delay = delay(deadline); - - task.enter(|| assert_not_ready!(delay.poll())); - - handle.advance(Duration::from_secs(1)); - - assert!(task.is_notified()); + assert!(delay.is_woken()); assert_ready!(delay.poll()); }); } diff --git a/tokio-timer/CHANGELOG.md b/tokio-timer/CHANGELOG.md deleted file mode 100644 index fecbcf5eb..000000000 --- a/tokio-timer/CHANGELOG.md +++ /dev/null @@ -1,102 +0,0 @@ -# 0.3.0-alpha.6 (September 30, 2019) - -- Move to `futures-*-preview 0.3.0-alpha.19` -- Move to `pin-project 0.4` - -# 0.3.0-alpha.5 (September 19, 2019) - -### Changed -- rename `sleep` to `delay_for` (#1518). - -# 0.3.0-alpha.4 (August 29, 2019) - -- Track tokio release. - -# 0.3.0-alpha.3 (August 28, 2019) - -### Changed -- `delay(...)` instead of `Delay::new(...)` (#1440). - -# 0.3.0-alpha.2 (August 17, 2019) - -### Changed -- Update `futures` dependency to 0.3.0-alpha.18. -- Switch `with_default(..., || )` to `set_default(...) -> Guard` (#1449). - -# 0.3.0-alpha.1 (August 8, 2019) - -### Changed -- Switch to `async`, `await`, and `std::future`. - -# 0.2.11 (May 14, 2019) - -### Added -- `Handle::timeout` API, replacing the deprecated `Handle::deadline` (#1074). - -# 0.2.10 (February 4, 2019) - -### Fixed -- `DelayQueue` when multiple delays are reset (#871). - -# 0.2.9 (January 24, 2019) - -### Fixed -- `DelayQueue` timing logic when inserting / resetting a delay (#851, #863). -- Documentation links (#842, #844, #845) - -# 0.2.8 (November 21, 2018) - -* Implement throttle combinator (#736). -* Derive `Clone` for `delay_queue::Key` (#730). -* Bump internal dependencies (#753). - -# 0.2.7 (September 27, 2018) - -* Fix `Timeout` on error bug (#648). -* Miscellaneous documentation improvements. - -# 0.2.6 (August 23, 2018) - -* Implement `Default` for `timer::Handle` (#553) -* Provide `DelayQueue` utility (#550) -* Reduce size of `Delay` struct (#554) -* Introduce `Timeout`, deprecate `Deadline` (#558) - -# 0.2.5 (August 6, 2018) - -* Add `Interval::interval` shortcut (#492). - -# 0.2.4 (June 6, 2018) - -* Add `sleep` function for easy interval delays (#347). -* Provide `clock::now()`, a configurable source of time (#381). - -# 0.2.3 (May 2, 2018) - -* Improve parking semantics (#327). - -# 0.2.2 (Skipped due to failure in counting module) - -# 0.2.1 (April 2, 2018) - -* Fix build on 32-bit systems (#274). - -# 0.2.0 (March 30, 2018) - -* Rewrite from scratch using a hierarchical wheel strategy (#249). - -# 0.1.2 (Jun 27, 2017) - -* Allow naming timer thread. -* Track changes in dependencies. - -# 0.1.1 (Apr 6, 2017) - -* Set Rust v1.14 as the minimum supported version. -* Fix bug related to intervals. -* Impl `PartialEq + Eq` for TimerError. -* Add `Debug` implementations. - -# 0.1.0 (Jan 11, 2017) - -* Initial Release diff --git a/tokio-timer/Cargo.toml b/tokio-timer/Cargo.toml deleted file mode 100644 index f6af121fc..000000000 --- a/tokio-timer/Cargo.toml +++ /dev/null @@ -1,46 +0,0 @@ -[package] -name = "tokio-timer" -# When releasing to crates.io: -# - Remove path dependencies -# - Update html_root_url. -# - Update doc url -# - Cargo.toml -# - README.md -# - Update CHANGELOG.md. -# - Create "v0.3.x" git tag. -version = "0.3.0-alpha.6" -edition = "2018" -authors = ["Tokio Contributors "] -license = "MIT" -readme = "README.md" -documentation = "https://docs.rs/tokio-timer/0.3.0-alpha.6/tokio_timer" -repository = "https://github.com/tokio-rs/tokio" -homepage = "https://github.com/tokio-rs/tokio" -description = """ -Timer facilities for Tokio -""" - -[features] -async-traits = [] - -[dependencies] -tokio-executor = { version = "=0.2.0-alpha.6", path = "../tokio-executor" } -tokio-sync = { version = "=0.2.0-alpha.6", path = "../tokio-sync" } - -futures-core-preview = "=0.3.0-alpha.19" -futures-util-preview = "=0.3.0-alpha.19" - -crossbeam-utils = "0.6.0" -# Backs `DelayQueue` -slab = "0.4.1" -# optionals - -[dev-dependencies] -tokio = { version = "=0.2.0-alpha.6", path = "../tokio" } -tokio-sync = { version = "=0.2.0-alpha.6", path = "../tokio-sync", features = ["async-traits"] } -tokio-test = { version = "=0.2.0-alpha.6", path = "../tokio-test" } - -rand = "0.7" - -[package.metadata.docs.rs] -all-features = true diff --git a/tokio-timer/LICENSE b/tokio-timer/LICENSE deleted file mode 100644 index cdb28b4b5..000000000 --- a/tokio-timer/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2019 Tokio Contributors - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/tokio-timer/README.md b/tokio-timer/README.md deleted file mode 100644 index d3f07640c..000000000 --- a/tokio-timer/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# tokio-timer - -Timer facilities for Tokio - -## License - -This project is licensed under the [MIT license](LICENSE). - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in Tokio by you, shall be licensed as MIT, without any additional -terms or conditions. diff --git a/tokio-timer/src/lib.rs b/tokio-timer/src/lib.rs deleted file mode 100644 index b54f3b465..000000000 --- a/tokio-timer/src/lib.rs +++ /dev/null @@ -1,105 +0,0 @@ -#![doc(html_root_url = "https://docs.rs/tokio-timer/0.3.0-alpha.6")] -#![warn( - missing_debug_implementations, - missing_docs, - rust_2018_idioms, - unreachable_pub -)] -#![deny(intra_doc_link_resolution_failure)] -#![doc(test( - no_crate_inject, - attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) -))] - -//! Utilities for tracking time. -//! -//! This crate provides a number of utilities for working with periods of time: -//! -//! * [`Delay`]: A future that completes at a specified instant in time. -//! -//! * [`Interval`] A stream that yields at fixed time intervals. -//! -//! * [`Throttle`]: Throttle down a stream by enforcing a fixed delay between items. -//! -//! * [`Timeout`]: Wraps a future or stream, setting an upper bound to the -//! amount of time it is allowed to execute. If the future or stream does not -//! complete in time, then it is canceled and an error is returned. -//! -//! * [`DelayQueue`]: A queue where items are returned once the requested delay -//! has expired. -//! -//! These three types are backed by a [`Timer`] instance. In order for -//! [`Delay`], [`Interval`], and [`Timeout`] to function, the associated -//! [`Timer`] instance must be running on some thread. -//! -//! [`Delay`]: struct.Delay.html -//! [`DelayQueue`]: struct.DelayQueue.html -//! [`Throttle`]: throttle::Throttle -//! [`Timeout`]: struct.Timeout.html -//! [`Interval`]: struct.Interval.html -//! [`Timer`]: timer::Timer - -pub mod clock; -pub mod delay_queue; -#[cfg(feature = "async-traits")] -pub mod throttle; -pub mod timeout; -pub mod timer; - -mod atomic; -mod delay; -mod error; -mod interval; -mod wheel; - -pub use delay::Delay; -#[doc(inline)] -pub use delay_queue::DelayQueue; -pub use error::Error; -pub use interval::Interval; -#[doc(inline)] -pub use timeout::Timeout; -pub use timer::{set_default, Timer}; - -use std::time::{Duration, Instant}; - -/// Create a Future that completes at `deadline`. -pub fn delay(deadline: Instant) -> Delay { - Delay::new(deadline) -} - -/// Create a Future that completes in `duration` from now. -/// -/// Equivalent to `delay(tokio_timer::clock::now() + duration)`. Analogous to `std::thread::sleep`. -pub fn delay_for(duration: Duration) -> Delay { - delay(clock::now() + duration) -} - -// ===== Internal utils ===== - -enum Round { - Up, - Down, -} - -/// Convert a `Duration` to milliseconds, rounding up and saturating at -/// `u64::MAX`. -/// -/// The saturating is fine because `u64::MAX` milliseconds are still many -/// million years. -#[inline] -fn ms(duration: Duration, round: Round) -> u64 { - const NANOS_PER_MILLI: u32 = 1_000_000; - const MILLIS_PER_SEC: u64 = 1_000; - - // Round up. - let millis = match round { - Round::Up => (duration.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI, - Round::Down => duration.subsec_millis(), - }; - - duration - .as_secs() - .saturating_mul(MILLIS_PER_SEC) - .saturating_add(u64::from(millis)) -} diff --git a/tokio-timer/tests/support/mod.rs b/tokio-timer/tests/support/mod.rs deleted file mode 100644 index f444a534e..000000000 --- a/tokio-timer/tests/support/mod.rs +++ /dev/null @@ -1,265 +0,0 @@ -#![allow(unused_macros, unused_imports, dead_code, deprecated)] - -use tokio_executor::park::{Park, Unpark}; -use tokio_timer::clock::Now; -use tokio_timer::timer::Timer; - -use futures::future::{lazy, Future}; - -use std::marker::PhantomData; -use std::rc::Rc; -use std::sync::{Arc, Mutex}; -use std::time::{Duration, Instant}; - -#[macro_export] -macro_rules! assert_ready { - ($f:expr) => {{ - use ::futures::Async::*; - - match $f.poll().unwrap() { - Ready(v) => v, - NotReady => panic!("NotReady"), - } - }}; - ($f:expr, $($msg:expr),+) => {{ - use ::futures::Async::*; - - match $f.poll().unwrap() { - Ready(v) => v, - NotReady => { - let msg = format!($($msg),+); - panic!("NotReady; {}", msg) - } - } - }} -} - -#[macro_export] -macro_rules! assert_ready_eq { - ($f:expr, $expect:expr) => { - assert_eq!($f.poll().unwrap(), ::futures::Async::Ready($expect)); - }; -} - -#[macro_export] -macro_rules! assert_not_ready { - ($f:expr) => {{ - let res = $f.poll().unwrap(); - assert!(!res.is_ready(), "actual={:?}", res) - }}; - ($f:expr, $($msg:expr),+) => {{ - let res = $f.poll().unwrap(); - if res.is_ready() { - let msg = format!($($msg),+); - panic!("actual={:?}; {}", res, msg); - } - }}; -} - -#[macro_export] -macro_rules! assert_elapsed { - ($f:expr) => { - assert!($f.poll().unwrap_err().is_elapsed()); - }; -} - -#[derive(Debug)] -pub struct MockTime { - inner: Inner, - _p: PhantomData>, -} - -#[derive(Debug)] -pub struct MockNow { - inner: Inner, -} - -#[derive(Debug)] -pub struct MockPark { - inner: Inner, - _p: PhantomData>, -} - -#[derive(Debug)] -pub struct MockUnpark { - inner: Inner, -} - -type Inner = Arc>; - -#[derive(Debug)] -struct State { - base: Instant, - advance: Duration, - unparked: bool, - park_for: Option, -} - -pub fn ms(num: u64) -> Duration { - Duration::from_millis(num) -} - -pub trait IntoTimeout { - fn into_timeout(self) -> Option; -} - -impl IntoTimeout for Option { - fn into_timeout(self) -> Self { - self - } -} - -impl IntoTimeout for Duration { - fn into_timeout(self) -> Option { - Some(self) - } -} - -/// Turn the timer state once -pub fn turn(timer: &mut Timer, duration: T) { - timer.turn(duration.into_timeout()).unwrap(); -} - -/// Advance the timer the specified amount -pub fn advance(timer: &mut Timer, duration: Duration) { - let inner = timer.get_park().inner.clone(); - let deadline = inner.lock().unwrap().now() + duration; - - while inner.lock().unwrap().now() < deadline { - let dur = deadline - inner.lock().unwrap().now(); - turn(timer, dur); - } -} - -pub fn mocked(f: F) -> R -where - F: FnOnce(&mut Timer, &mut MockTime) -> R, -{ - mocked_with_now(Instant::now(), f) -} - -pub fn mocked_with_now(now: Instant, f: F) -> R -where - F: FnOnce(&mut Timer, &mut MockTime) -> R, -{ - let mut time = MockTime::new(now); - let park = time.mock_park(); - let now = ::tokio_timer::clock::Clock::new_with_now(time.mock_now()); - - let mut enter = ::tokio_executor::enter().unwrap(); - - ::tokio_timer::clock::with_default(&now, &mut enter, |enter| { - let mut timer = Timer::new(park); - let handle = timer.handle(); - - ::tokio_timer::with_default(&handle, enter, |_| { - lazy(|| Ok::<_, ()>(f(&mut timer, &mut time))) - .wait() - .unwrap() - }) - }) -} - -impl MockTime { - pub fn new(now: Instant) -> MockTime { - let state = State { - base: now, - advance: Duration::default(), - unparked: false, - park_for: None, - }; - - MockTime { - inner: Arc::new(Mutex::new(state)), - _p: PhantomData, - } - } - - pub fn mock_now(&self) -> MockNow { - let inner = self.inner.clone(); - MockNow { inner } - } - - pub fn mock_park(&self) -> MockPark { - let inner = self.inner.clone(); - MockPark { - inner, - _p: PhantomData, - } - } - - pub fn now(&self) -> Instant { - self.inner.lock().unwrap().now() - } - - /// Returns the total amount of time the time has been advanced. - pub fn advanced(&self) -> Duration { - self.inner.lock().unwrap().advance - } - - pub fn advance(&self, duration: Duration) { - let mut inner = self.inner.lock().unwrap(); - inner.advance(duration); - } - - /// The next call to park_timeout will be for this duration, regardless of - /// the timeout passed to `park_timeout`. - pub fn park_for(&self, duration: Duration) { - self.inner.lock().unwrap().park_for = Some(duration); - } -} - -impl Park for MockPark { - type Unpark = MockUnpark; - type Error = (); - - fn unpark(&self) -> Self::Unpark { - let inner = self.inner.clone(); - MockUnpark { inner } - } - - fn park(&mut self) -> Result<(), Self::Error> { - let mut inner = self.inner.lock().map_err(|_| ())?; - - let duration = inner.park_for.take().expect("call park_for first"); - - inner.advance(duration); - Ok(()) - } - - fn park_timeout(&mut self, duration: Duration) -> Result<(), Self::Error> { - let mut inner = self.inner.lock().unwrap(); - - if let Some(duration) = inner.park_for.take() { - inner.advance(duration); - } else { - inner.advance(duration); - } - - Ok(()) - } -} - -impl Unpark for MockUnpark { - fn unpark(&self) { - if let Ok(mut inner) = self.inner.lock() { - inner.unparked = true; - } - } -} - -impl Now for MockNow { - fn now(&self) -> Instant { - self.inner.lock().unwrap().now() - } -} - -impl State { - fn now(&self) -> Instant { - self.base + self.advance - } - - fn advance(&mut self, duration: Duration) { - self.advance += duration; - } -} diff --git a/tokio/Cargo.toml b/tokio/Cargo.toml index 1084db0f8..bbd9e75b5 100644 --- a/tokio/Cargo.toml +++ b/tokio/Cargo.toml @@ -59,7 +59,7 @@ rt-full = [ signal = ["tokio-net/signal"] sync = ["tokio-sync"] tcp = ["io", "tokio-net/tcp"] -timer = ["tokio-timer"] +timer = ["crossbeam-utils", "slab"] tracing = ["tracing-core"] udp = ["io", "tokio-net/udp"] uds = ["io", "tokio-net/uds"] @@ -72,14 +72,16 @@ futures-util-preview = { version = "=0.3.0-alpha.19", features = ["sink"] } # Everything else is optional... bytes = { version = "0.4", optional = true } +crossbeam-utils = { version = "0.6.0", optional = true } num_cpus = { version = "1.8.0", optional = true } +# Backs `DelayQueue` +slab = { version = "0.4.1", optional = true } tokio-codec = { version = "=0.2.0-alpha.6", optional = true, path = "../tokio-codec" } tokio-io = { version = "=0.2.0-alpha.6", optional = true, features = ["util"], path = "../tokio-io" } tokio-executor = { version = "=0.2.0-alpha.6", optional = true, path = "../tokio-executor" } tokio-macros = { version = "=0.2.0-alpha.6", optional = true, path = "../tokio-macros" } tokio-net = { version = "=0.2.0-alpha.6", optional = true, features = ["async-traits"], path = "../tokio-net" } tokio-sync = { version = "=0.2.0-alpha.6", optional = true, path = "../tokio-sync", features = ["async-traits"] } -tokio-timer = { version = "=0.3.0-alpha.6", optional = true, path = "../tokio-timer", features = ["async-traits"] } tracing-core = { version = "0.1", optional = true } [target.'cfg(feature = "tracing")'.dependencies] @@ -98,6 +100,7 @@ http = "0.1" httparse = "1.0" libc = "0.2" num_cpus = "1.0" +rand = "0.7.2" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" tempfile = "3.1.0" diff --git a/tokio/src/clock.rs b/tokio/src/clock.rs index 7ddbbf37f..d574af857 100644 --- a/tokio/src/clock.rs +++ b/tokio/src/clock.rs @@ -2,14 +2,13 @@ //! //! This module provides the [`now`][n] function, which returns an `Instant` //! representing "now". The source of time used by this function is configurable -//! (via the [`tokio-timer`] crate) and allows mocking out the source of time in -//! tests or performing caching operations to reduce the number of syscalls. +//! and allows mocking out the source of time in tests or performing caching +//! operations to reduce the number of syscalls. //! //! Note that, because the source of time is configurable, it is possible to //! observe non-monotonic behavior when calling [`now`][n] from different //! executors. //! //! [n]: fn.now.html -//! [`tokio-timer`]: https://docs.rs/tokio-timer/0.2/tokio_timer/clock/index.html -pub use tokio_timer::clock::now; +pub use crate::timer::clock::now; diff --git a/tokio/src/future.rs b/tokio/src/future.rs index a904d6293..2a714a3e0 100644 --- a/tokio/src/future.rs +++ b/tokio/src/future.rs @@ -1,7 +1,7 @@ //! Asynchronous values. #[cfg(feature = "timer")] -use tokio_timer::Timeout; +use crate::timer::Timeout; #[cfg(feature = "timer")] use std::time::Duration; diff --git a/tokio/src/runtime/current_thread/builder.rs b/tokio/src/runtime/current_thread/builder.rs index d48136d4c..4837e4e25 100644 --- a/tokio/src/runtime/current_thread/builder.rs +++ b/tokio/src/runtime/current_thread/builder.rs @@ -1,9 +1,9 @@ use crate::runtime::current_thread::Runtime; +use crate::timer::clock::Clock; +use crate::timer::timer::Timer; use tokio_executor::current_thread::CurrentThread; use tokio_net::driver::Reactor; -use tokio_timer::clock::Clock; -use tokio_timer::timer::Timer; use std::io; @@ -24,7 +24,7 @@ use std::io; /// /// ``` /// use tokio::runtime::current_thread::Builder; -/// use tokio_timer::clock::Clock; +/// use tokio::timer::clock::Clock; /// /// # pub fn main() { /// // build Runtime @@ -66,7 +66,7 @@ impl Builder { // Place a timer wheel on top of the reactor. If there are no timeouts to fire, it'll let the // reactor pick up some new external events. - let timer = Timer::new_with_now(reactor, self.clock.clone()); + let timer = Timer::new_with_clock(reactor, self.clock.clone()); let timer_handle = timer.handle(); // And now put a single-threaded executor on top of the timer. When there are no futures ready diff --git a/tokio/src/runtime/current_thread/runtime.rs b/tokio/src/runtime/current_thread/runtime.rs index f9e3623d9..833e856e1 100644 --- a/tokio/src/runtime/current_thread/runtime.rs +++ b/tokio/src/runtime/current_thread/runtime.rs @@ -1,10 +1,10 @@ use crate::runtime::current_thread::Builder; +use crate::timer::clock::{self, Clock}; +use crate::timer::timer::{self, Timer}; use tokio_executor::current_thread::Handle as ExecutorHandle; use tokio_executor::current_thread::{self, CurrentThread}; use tokio_net::driver::{self, Reactor}; -use tokio_timer::clock::{self, Clock}; -use tokio_timer::timer::{self, Timer}; use std::error::Error; use std::fmt; diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs index f696272b3..2fcd1dc3a 100644 --- a/tokio/src/runtime/mod.rs +++ b/tokio/src/runtime/mod.rs @@ -20,7 +20,7 @@ //! //! * Spawn a background thread running a [`Reactor`] instance. //! * Start a [`ThreadPool`] for executing futures. -//! * Run an instance of [`Timer`] **per** thread pool worker thread. +//! * Run an instance of `Timer` **per** thread pool worker thread. //! //! The thread pool uses a work-stealing strategy and is configured to start a //! worker thread for each CPU core available on the system. This tends to be @@ -127,7 +127,6 @@ //! [`ThreadPool`]: https://docs.rs/tokio-executor/0.2.0-alpha.2/tokio_executor/threadpool/struct.ThreadPool.html //! [`run`]: fn.run.html //! [`tokio::spawn`]: ../executor/fn.spawn.html -//! [`Timer`]: https://docs.rs/tokio-timer/0.2/tokio_timer/timer/struct.Timer.html //! [`tokio::main`]: ../../tokio_macros/attr.main.html pub mod current_thread; diff --git a/tokio/src/runtime/threadpool/builder.rs b/tokio/src/runtime/threadpool/builder.rs index a45abdbce..7f6f27f46 100644 --- a/tokio/src/runtime/threadpool/builder.rs +++ b/tokio/src/runtime/threadpool/builder.rs @@ -1,9 +1,9 @@ use super::{Inner, Runtime}; +use crate::timer::clock::{self, Clock}; +use crate::timer::timer::{self, Timer}; use tokio_executor::thread_pool; use tokio_net::driver::{self, Reactor}; -use tokio_timer::clock::{self, Clock}; -use tokio_timer::timer::{self, Timer}; use tracing_core as trace; use std::{fmt, io}; @@ -26,7 +26,7 @@ use std::sync::{Arc, Mutex}; /// /// ``` /// use tokio::runtime::Builder; -/// use tokio_timer::clock::Clock; +/// use tokio::timer::clock::Clock; /// /// fn main() { /// // build Runtime @@ -233,7 +233,7 @@ impl Builder { reactor_handles.push(reactor.handle()); // Create a new timer. - let timer = Timer::new_with_now(reactor, self.clock.clone()); + let timer = Timer::new_with_clock(reactor, self.clock.clone()); timer_handles.push(timer.handle()); timers.push(Mutex::new(Some(timer))); } diff --git a/tokio/src/runtime/threadpool/mod.rs b/tokio/src/runtime/threadpool/mod.rs index 0717589c8..e23cda4d6 100644 --- a/tokio/src/runtime/threadpool/mod.rs +++ b/tokio/src/runtime/threadpool/mod.rs @@ -9,9 +9,10 @@ pub use self::spawner::Spawner; #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411 pub use tokio_executor::thread_pool::JoinHandle; +use crate::timer::timer; + use tokio_executor::thread_pool::ThreadPool; use tokio_net::driver; -use tokio_timer::timer; use tracing_core as trace; use std::future::Future; diff --git a/tokio/src/stream.rs b/tokio/src/stream.rs index 3faaae951..e4f5a1b1f 100644 --- a/tokio/src/stream.rs +++ b/tokio/src/stream.rs @@ -4,7 +4,7 @@ use std::time::Duration; #[cfg(feature = "timer")] -use tokio_timer::{throttle::Throttle, Timeout}; +use crate::timer::{throttle::Throttle, Timeout}; #[doc(inline)] pub use futures_core::Stream; diff --git a/tokio-timer/src/atomic.rs b/tokio/src/timer/atomic.rs similarity index 100% rename from tokio-timer/src/atomic.rs rename to tokio/src/timer/atomic.rs diff --git a/tokio-timer/src/clock/mod.rs b/tokio/src/timer/clock/mod.rs similarity index 96% rename from tokio-timer/src/clock/mod.rs rename to tokio/src/timer/clock/mod.rs index a4cd2b3f6..d7f7c31c5 100644 --- a/tokio-timer/src/clock/mod.rs +++ b/tokio/src/timer/clock/mod.rs @@ -20,7 +20,6 @@ mod now; pub use self::now::Now; -use crate::timer; use std::cell::Cell; use std::fmt; use std::sync::Arc; @@ -57,7 +56,7 @@ thread_local! { /// # Examples /// /// ``` -/// # use tokio_timer::clock; +/// # use tokio::timer::clock; /// let now = clock::now(); /// ``` pub fn now() -> Instant { @@ -102,13 +101,6 @@ impl Clock { } } -#[allow(deprecated)] -impl timer::Now for Clock { - fn now(&mut self) -> Instant { - Clock::now(self) - } -} - impl fmt::Debug for Clock { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_struct("Clock") diff --git a/tokio-timer/src/clock/now.rs b/tokio/src/timer/clock/now.rs similarity index 100% rename from tokio-timer/src/clock/now.rs rename to tokio/src/timer/clock/now.rs diff --git a/tokio-timer/src/deadline.rs b/tokio/src/timer/deadline.rs similarity index 100% rename from tokio-timer/src/deadline.rs rename to tokio/src/timer/deadline.rs diff --git a/tokio-timer/src/delay.rs b/tokio/src/timer/delay.rs similarity index 96% rename from tokio-timer/src/delay.rs rename to tokio/src/timer/delay.rs index e613622ae..a48510f4b 100644 --- a/tokio-timer/src/delay.rs +++ b/tokio/src/timer/delay.rs @@ -1,4 +1,5 @@ -use crate::timer::{HandlePriv, Registration}; +use crate::timer::timer::{HandlePriv, Registration}; + use futures_core::ready; use std::future::Future; use std::pin::Pin; @@ -78,8 +79,6 @@ impl Delay { self.registration.reset(deadline); } - // Used by `Timeout` - #[cfg(feature = "async-traits")] pub(crate) fn reset_timeout(&mut self) { self.registration.reset_timeout(); } diff --git a/tokio-timer/src/delay_queue.rs b/tokio/src/timer/delay_queue.rs similarity index 97% rename from tokio-timer/src/delay_queue.rs rename to tokio/src/timer/delay_queue.rs index db5ddc578..70cc74e5a 100644 --- a/tokio-timer/src/delay_queue.rs +++ b/tokio/src/timer/delay_queue.rs @@ -4,10 +4,10 @@ //! //! [`DelayQueue`]: struct.DelayQueue.html -use crate::clock::now; -use crate::timer::Handle; -use crate::wheel::{self, Wheel}; -use crate::{Delay, Error}; +use crate::timer::clock::now; +use crate::timer::timer::Handle; +use crate::timer::wheel::{self, Wheel}; +use crate::timer::{Delay, Error}; use futures_core::ready; use slab::Slab; @@ -217,7 +217,7 @@ impl DelayQueue { /// # Examples /// /// ```rust - /// # use tokio_timer::DelayQueue; + /// # use tokio::timer::DelayQueue; /// let delay_queue: DelayQueue = DelayQueue::new(); /// ``` pub fn new() -> DelayQueue { @@ -231,8 +231,8 @@ impl DelayQueue { /// # Examples /// /// ```rust,no_run - /// # use tokio_timer::DelayQueue; - /// use tokio_timer::timer::Handle; + /// # use tokio::timer::DelayQueue; + /// use tokio::timer::timer::Handle; /// /// let handle = Handle::default(); /// let delay_queue: DelayQueue = DelayQueue::with_capacity_and_handle(0, &handle); @@ -258,7 +258,7 @@ impl DelayQueue { /// # Examples /// /// ```rust - /// # use tokio_timer::DelayQueue; + /// # use tokio::timer::DelayQueue; /// # use std::time::Duration; /// let mut delay_queue = DelayQueue::with_capacity(10); /// @@ -464,7 +464,7 @@ impl DelayQueue { /// assert_eq!(*item.get_ref(), "foo"); /// ``` pub fn remove(&mut self, key: &Key) -> Expired { - use crate::wheel::Stack; + use crate::timer::wheel::Stack; // Special case the `expired` queue if self.slab[key.index].expired { @@ -607,7 +607,7 @@ impl DelayQueue { /// # Examples /// /// ```rust - /// use tokio_timer::DelayQueue; + /// use tokio::timer::DelayQueue; /// /// let delay_queue: DelayQueue = DelayQueue::with_capacity(10); /// assert_eq!(delay_queue.capacity(), 10); @@ -636,7 +636,7 @@ impl DelayQueue { /// # Examples /// /// ``` - /// use tokio_timer::DelayQueue; + /// use tokio::timer::DelayQueue; /// use std::time::Duration; /// /// let mut delay_queue = DelayQueue::new(); @@ -658,7 +658,7 @@ impl DelayQueue { /// # Examples /// /// ``` - /// use tokio_timer::DelayQueue; + /// use tokio::timer::DelayQueue; /// use std::time::Duration; /// /// let mut delay_queue = DelayQueue::new(); @@ -690,7 +690,8 @@ impl DelayQueue { ready!(Pin::new(&mut *delay).poll(cx)); } - let now = crate::ms(delay.deadline() - self.start, crate::Round::Down); + let now = + crate::timer::ms(delay.deadline() - self.start, crate::timer::Round::Down); self.poll = wheel::Poll::new(now); } @@ -713,7 +714,7 @@ impl DelayQueue { let when = if when < self.start { 0 } else { - crate::ms(when - self.start, crate::Round::Up) + crate::timer::ms(when - self.start, crate::timer::Round::Up) }; cmp::max(when, self.wheel.elapsed()) @@ -723,7 +724,6 @@ impl DelayQueue { // We never put `T` in a `Pin`... impl Unpin for DelayQueue {} -#[cfg(feature = "async-traits")] impl futures_core::Stream for DelayQueue { // DelayQueue seems much more specific, where a user may care that it // has reached capacity, so return those errors instead of panicking. diff --git a/tokio-timer/src/error.rs b/tokio/src/timer/error.rs similarity index 100% rename from tokio-timer/src/error.rs rename to tokio/src/timer/error.rs diff --git a/tokio-timer/src/interval.rs b/tokio/src/timer/interval.rs similarity index 93% rename from tokio-timer/src/interval.rs rename to tokio/src/timer/interval.rs index 8e103c667..de0c1ba5c 100644 --- a/tokio-timer/src/interval.rs +++ b/tokio/src/timer/interval.rs @@ -1,5 +1,4 @@ -use crate::clock; -use crate::Delay; +use crate::timer::{clock, Delay}; use futures_core::ready; use futures_util::future::poll_fn; @@ -40,7 +39,7 @@ impl Interval { /// Creates new `Interval` that yields with interval of `duration`. /// - /// The function is shortcut for `Interval::new(tokio_timer::clock::now() + duration, duration)`. + /// The function is shortcut for `Interval::new(tokio::timer::clock::now() + duration, duration)`. /// /// The `duration` argument must be a non-zero duration. /// @@ -98,14 +97,12 @@ impl Interval { } } -#[cfg(feature = "async-traits")] impl futures_core::FusedStream for Interval { fn is_terminated(&self) -> bool { false } } -#[cfg(feature = "async-traits")] impl futures_core::Stream for Interval { type Item = Instant; diff --git a/tokio/src/timer.rs b/tokio/src/timer/mod.rs similarity index 59% rename from tokio/src/timer.rs rename to tokio/src/timer/mod.rs index eaedee27e..d05dca84d 100644 --- a/tokio/src/timer.rs +++ b/tokio/src/timer/mod.rs @@ -74,6 +74,75 @@ //! [Interval]: struct.Interval.html //! [`DelayQueue`]: struct.DelayQueue.html -pub use tokio_timer::{ - delay, delay_for, delay_queue, timeout, Delay, DelayQueue, Error, Interval, Timeout, -}; +pub mod clock; + +pub mod delay_queue; +#[doc(inline)] +pub use self::delay_queue::DelayQueue; + +pub mod throttle; + +// TODO: clean this up +#[allow(clippy::module_inception)] +pub mod timer; +pub use timer::{set_default, Timer}; + +pub mod timeout; +#[doc(inline)] +pub use timeout::Timeout; + +mod atomic; + +mod delay; +pub use self::delay::Delay; + +mod error; +pub use error::Error; + +mod interval; +pub use interval::Interval; + +mod wheel; + +use std::time::{Duration, Instant}; + +/// Create a Future that completes at `deadline`. +pub fn delay(deadline: Instant) -> Delay { + Delay::new(deadline) +} + +/// Create a Future that completes in `duration` from now. +/// +/// Equivalent to `delay(tokio::timer::clock::now() + duration)`. Analogous to `std::thread::sleep`. +pub fn delay_for(duration: Duration) -> Delay { + delay(clock::now() + duration) +} + +// ===== Internal utils ===== + +enum Round { + Up, + Down, +} + +/// Convert a `Duration` to milliseconds, rounding up and saturating at +/// `u64::MAX`. +/// +/// The saturating is fine because `u64::MAX` milliseconds are still many +/// million years. +#[inline] +fn ms(duration: Duration, round: Round) -> u64 { + const NANOS_PER_MILLI: u32 = 1_000_000; + const MILLIS_PER_SEC: u64 = 1_000; + + // Round up. + let millis = match round { + Round::Up => (duration.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI, + Round::Down => duration.subsec_millis(), + }; + + duration + .as_secs() + .saturating_mul(MILLIS_PER_SEC) + .saturating_add(u64::from(millis)) +} diff --git a/tokio-timer/src/throttle.rs b/tokio/src/timer/throttle.rs similarity index 98% rename from tokio-timer/src/throttle.rs rename to tokio/src/timer/throttle.rs index 7f554409e..5c46adde6 100644 --- a/tokio-timer/src/throttle.rs +++ b/tokio/src/timer/throttle.rs @@ -1,6 +1,7 @@ //! Slow down a stream by enforcing a delay between items. -use crate::{clock, Delay}; +use crate::timer::{clock, Delay}; + use futures_core::ready; use futures_core::Stream; use std::{ diff --git a/tokio-timer/src/timeout.rs b/tokio/src/timer/timeout.rs similarity index 98% rename from tokio-timer/src/timeout.rs rename to tokio/src/timer/timeout.rs index 0b9d0110a..7d028aa68 100644 --- a/tokio-timer/src/timeout.rs +++ b/tokio/src/timer/timeout.rs @@ -4,9 +4,9 @@ //! //! [`Timeout`]: struct.Timeout.html -use crate::clock::now; -use crate::Delay; -#[cfg(feature = "async-traits")] +use crate::timer::clock::now; +use crate::timer::Delay; + use futures_core::ready; use std::fmt; use std::future::Future; @@ -180,7 +180,6 @@ where } } -#[cfg(feature = "async-traits")] impl futures_core::Stream for Timeout where T: futures_core::Stream, diff --git a/tokio-timer/src/timer/atomic_stack.rs b/tokio/src/timer/timer/atomic_stack.rs similarity index 99% rename from tokio-timer/src/timer/atomic_stack.rs rename to tokio/src/timer/timer/atomic_stack.rs index 0574e939a..849e79a33 100644 --- a/tokio-timer/src/timer/atomic_stack.rs +++ b/tokio/src/timer/timer/atomic_stack.rs @@ -1,5 +1,6 @@ use super::Entry; -use crate::Error; +use crate::timer::Error; + use std::ptr; use std::sync::atomic::AtomicPtr; use std::sync::atomic::Ordering::SeqCst; diff --git a/tokio-timer/src/timer/entry.rs b/tokio/src/timer/timer/entry.rs similarity index 99% rename from tokio-timer/src/timer/entry.rs rename to tokio/src/timer/timer/entry.rs index 6d30f84c9..a31dda4a7 100644 --- a/tokio-timer/src/timer/entry.rs +++ b/tokio/src/timer/timer/entry.rs @@ -1,6 +1,9 @@ -use crate::atomic::AtomicU64; -use crate::timer::{HandlePriv, Inner}; -use crate::Error; +use crate::timer::atomic::AtomicU64; +use crate::timer::timer::{HandlePriv, Inner}; +use crate::timer::Error; + +use tokio_sync::AtomicWaker; + use crossbeam_utils::CachePadded; use std::cell::UnsafeCell; use std::ptr; @@ -10,7 +13,6 @@ use std::sync::{Arc, Weak}; use std::task::{self, Poll}; use std::time::{Duration, Instant}; use std::u64; -use tokio_sync::AtomicWaker; /// Internal state shared between a `Delay` instance and the timer. /// diff --git a/tokio-timer/src/timer/handle.rs b/tokio/src/timer/timer/handle.rs similarity index 98% rename from tokio-timer/src/timer/handle.rs rename to tokio/src/timer/timer/handle.rs index a6ddfd341..dbff2be72 100644 --- a/tokio-timer/src/timer/handle.rs +++ b/tokio/src/timer/timer/handle.rs @@ -1,6 +1,7 @@ -use crate::clock::now; -use crate::timer::Inner; -use crate::{Delay, Error, /*Interval,*/ Timeout}; +use crate::timer::clock::now; +use crate::timer::timer::Inner; +use crate::timer::{Delay, Error, Timeout}; + use std::cell::RefCell; use std::fmt; use std::marker::PhantomData; diff --git a/tokio-timer/src/timer/mod.rs b/tokio/src/timer/timer/mod.rs similarity index 92% rename from tokio-timer/src/timer/mod.rs rename to tokio/src/timer/timer/mod.rs index ee384f15d..80e460de2 100644 --- a/tokio-timer/src/timer/mod.rs +++ b/tokio/src/timer/timer/mod.rs @@ -10,10 +10,6 @@ //! `Clone`, `Send`, and `Sync`. This type is used to create instances of //! [`Delay`]. //! -//! The [`Now`] trait describes how to get an [`Instant`] representing the -//! current moment in time. [`SystemNow`] is the default implementation, where -//! [`Now::now`] is implemented by calling [`Instant::now`]. -//! //! [`Timer`] is generic over [`Now`]. This allows the source of time to be //! customized. This ability is especially useful in tests and any environment //! where determinism is necessary. @@ -26,39 +22,38 @@ //! [`Delay`]: Delay //! [`Now`]: clock::Now //! [`Now::now`]: clock::Now::now -//! [`SystemNow`]: struct.SystemNow.html //! [`Instant`]: std::time::Instant //! [`Instant::now`]: std::time::Instant::now -// This allows the usage of the old `Now` trait. -#![allow(deprecated)] - mod atomic_stack; -mod entry; -mod handle; -mod now; -mod registration; -mod stack; - use self::atomic_stack::AtomicStack; -use self::entry::Entry; -use self::stack::Stack; +mod entry; +use self::entry::Entry; + +mod handle; pub(crate) use self::handle::HandlePriv; pub use self::handle::{set_default, Handle}; -pub use self::now::{Now, SystemNow}; + +mod registration; pub(crate) use self::registration::Registration; -use crate::atomic::AtomicU64; -use crate::wheel; -use crate::Error; +mod stack; +use self::stack::Stack; + +use crate::timer::atomic::AtomicU64; +use crate::timer::clock::Clock; +use crate::timer::wheel; +use crate::timer::Error; + +use tokio_executor::park::{Park, ParkThread, Unpark}; + use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::SeqCst; use std::sync::Arc; use std::time::{Duration, Instant}; use std::usize; use std::{cmp, fmt}; -use tokio_executor::park::{Park, ParkThread, Unpark}; /// Timer implementation that drives [`Delay`], [`Interval`], and [`Timeout`]. /// @@ -124,7 +119,7 @@ use tokio_executor::park::{Park, ParkThread, Unpark}; /// [`turn`]: #method.turn /// [Handle.struct]: struct.Handle.html #[derive(Debug)] -pub struct Timer { +pub struct Timer { /// Shared state inner: Arc, @@ -135,7 +130,7 @@ pub struct Timer { park: T, /// Source of "now" instances - now: N, + clock: Clock, } /// Return value from the `turn` method on `Timer`. @@ -183,11 +178,11 @@ where /// /// [`handle`]: #method.handle pub fn new(park: T) -> Self { - Timer::new_with_now(park, SystemNow::new()) + Timer::new_with_clock(park, Clock::new()) } } -impl Timer { +impl Timer { /// Returns a reference to the underlying `Park` instance. pub fn get_park(&self) -> &T { &self.park @@ -199,23 +194,22 @@ impl Timer { } } -impl Timer +impl Timer where T: Park, - N: Now, { /// Create a new `Timer` instance that uses `park` to block the current /// thread and `now` to get the current `Instant`. /// /// Specifying the source of time is useful when testing. - pub fn new_with_now(park: T, mut now: N) -> Self { + pub fn new_with_clock(park: T, clock: Clock) -> Self { let unpark = Box::new(park.unpark()); Timer { - inner: Arc::new(Inner::new(now.now(), unpark)), + inner: Arc::new(Inner::new(clock.now(), unpark)), wheel: wheel::Wheel::new(), park, - now, + clock, } } @@ -264,7 +258,10 @@ where /// Run timer related logic fn process(&mut self) { - let now = crate::ms(self.now.now() - self.inner.start, crate::Round::Down); + let now = crate::timer::ms( + self.clock.now() - self.inner.start, + crate::timer::Round::Down, + ); let mut poll = wheel::Poll::new(now); while let Some(entry) = self.wheel.poll(&mut poll, &mut ()) { @@ -315,7 +312,7 @@ where /// /// Returns `None` if the entry was fired. fn add_entry(&mut self, entry: Arc, when: u64) { - use crate::wheel::InsertError; + use crate::timer::wheel::InsertError; entry.set_when_internal(Some(when)); @@ -337,16 +334,15 @@ where } } -impl Default for Timer { +impl Default for Timer { fn default() -> Self { Timer::new(ParkThread::new()) } } -impl Park for Timer +impl Park for Timer where T: Park, - N: Now, { type Unpark = T::Unpark; type Error = T::Error; @@ -360,7 +356,7 @@ where match self.wheel.poll_at() { Some(when) => { - let now = self.now.now(); + let now = self.clock.now(); let deadline = self.expiration_instant(when); if deadline > now { @@ -384,7 +380,7 @@ where match self.wheel.poll_at() { Some(when) => { - let now = self.now.now(); + let now = self.clock.now(); let deadline = self.expiration_instant(when); if deadline > now { @@ -404,7 +400,7 @@ where } } -impl Drop for Timer { +impl Drop for Timer { fn drop(&mut self) { use std::u64; @@ -477,7 +473,7 @@ impl Inner { return 0; } - crate::ms(deadline - self.start, crate::Round::Up) + crate::timer::ms(deadline - self.start, crate::timer::Round::Up) } } diff --git a/tokio-timer/src/timer/now.rs b/tokio/src/timer/timer/now.rs similarity index 100% rename from tokio-timer/src/timer/now.rs rename to tokio/src/timer/timer/now.rs diff --git a/tokio-timer/src/timer/registration.rs b/tokio/src/timer/timer/registration.rs similarity index 94% rename from tokio-timer/src/timer/registration.rs rename to tokio/src/timer/timer/registration.rs index 9d7949a38..9dceb3c66 100644 --- a/tokio-timer/src/timer/registration.rs +++ b/tokio/src/timer/timer/registration.rs @@ -1,5 +1,6 @@ -use crate::timer::{Entry, HandlePriv}; -use crate::Error; +use crate::timer::timer::{Entry, HandlePriv}; +use crate::timer::Error; + use std::sync::Arc; use std::task::{self, Poll}; use std::time::{Duration, Instant}; @@ -45,7 +46,6 @@ impl Registration { } // Used by `Timeout` - #[cfg(feature = "async-traits")] pub(crate) fn reset_timeout(&mut self) { let deadline = crate::clock::now() + self.entry.time_ref().duration; unsafe { diff --git a/tokio-timer/src/timer/stack.rs b/tokio/src/timer/timer/stack.rs similarity index 98% rename from tokio-timer/src/timer/stack.rs rename to tokio/src/timer/timer/stack.rs index 9309b470b..41ae33ed3 100644 --- a/tokio-timer/src/timer/stack.rs +++ b/tokio/src/timer/timer/stack.rs @@ -1,5 +1,6 @@ -use super::Entry; -use crate::wheel; +use crate::timer::timer::Entry; +use crate::timer::wheel; + use std::ptr; use std::sync::Arc; diff --git a/tokio-timer/src/wheel/level.rs b/tokio/src/timer/wheel/level.rs similarity index 99% rename from tokio-timer/src/wheel/level.rs rename to tokio/src/timer/wheel/level.rs index d403e2327..a60896647 100644 --- a/tokio-timer/src/wheel/level.rs +++ b/tokio/src/timer/wheel/level.rs @@ -1,4 +1,5 @@ -use crate::wheel::Stack; +use crate::timer::wheel::Stack; + use std::fmt; /// Wheel for a single level in the timer. This wheel contains 64 slots. diff --git a/tokio-timer/src/wheel/mod.rs b/tokio/src/timer/wheel/mod.rs similarity index 100% rename from tokio-timer/src/wheel/mod.rs rename to tokio/src/timer/wheel/mod.rs index 3a9a51e13..e46345c62 100644 --- a/tokio-timer/src/wheel/mod.rs +++ b/tokio/src/timer/wheel/mod.rs @@ -1,8 +1,8 @@ mod level; -mod stack; - pub(crate) use self::level::Expiration; use self::level::Level; + +mod stack; pub(crate) use self::stack::Stack; use std::borrow::Borrow; diff --git a/tokio-timer/src/wheel/stack.rs b/tokio/src/timer/wheel/stack.rs similarity index 100% rename from tokio-timer/src/wheel/stack.rs rename to tokio/src/timer/wheel/stack.rs diff --git a/tokio/tests/clock.rs b/tokio/tests/clock.rs index 64f4b6076..0000fc6d5 100644 --- a/tokio/tests/clock.rs +++ b/tokio/tests/clock.rs @@ -1,17 +1,15 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "default")] use tokio::runtime::{self, current_thread}; +use tokio::timer::clock::Clock; use tokio::timer::*; -use tokio_timer; -use tokio_timer::clock::Clock; use std::sync::mpsc; use std::time::{Duration, Instant}; struct MockNow(Instant); -impl tokio_timer::clock::Now for MockNow { +impl tokio::timer::clock::Now for MockNow { fn now(&self) -> Instant { self.0 } diff --git a/tokio-timer/tests/clock.rs b/tokio/tests/timer_clock.rs similarity index 93% rename from tokio-timer/tests/clock.rs rename to tokio/tests/timer_clock.rs index 1dd9ac612..686fb2b1f 100644 --- a/tokio-timer/tests/clock.rs +++ b/tokio/tests/timer_clock.rs @@ -1,8 +1,9 @@ #![warn(rust_2018_idioms)] +use tokio::timer::clock; +use tokio::timer::clock::*; + use std::time::Instant; -use tokio_timer::clock; -use tokio_timer::clock::*; struct ConstNow(Instant); diff --git a/tokio-timer/tests/delay.rs b/tokio/tests/timer_delay.rs similarity index 99% rename from tokio-timer/tests/delay.rs rename to tokio/tests/timer_delay.rs index 17b7fcf80..eb7afca8c 100644 --- a/tokio-timer/tests/delay.rs +++ b/tokio/tests/timer_delay.rs @@ -1,11 +1,11 @@ #![warn(rust_2018_idioms)] -use std::time::{Duration, Instant}; - +use tokio::timer::delay; +use tokio::timer::timer::Handle; use tokio_test::task::MockTask; use tokio_test::{assert_pending, assert_ready, clock}; -use tokio_timer::delay; -use tokio_timer::timer::Handle; + +use std::time::{Duration, Instant}; #[test] fn immediate_delay() { diff --git a/tokio-timer/tests/hammer.rs b/tokio/tests/timer_hammer.rs similarity index 99% rename from tokio-timer/tests/hammer.rs rename to tokio/tests/timer_hammer.rs index eaf26c1f1..b53ff250a 100644 --- a/tokio-timer/tests/hammer.rs +++ b/tokio/tests/timer_hammer.rs @@ -1,8 +1,9 @@ #![warn(rust_2018_idioms)] +use tokio::timer::{Delay, Timer}; + use tokio_executor::current_thread::CurrentThread; use tokio_executor::park::{Park, Unpark, UnparkThread}; -use tokio_timer::{Delay, Timer}; use rand; use rand::Rng; diff --git a/tokio-timer/tests/interval.rs b/tokio/tests/timer_interval.rs similarity index 98% rename from tokio-timer/tests/interval.rs rename to tokio/tests/timer_interval.rs index 6f00a0a61..231aa129e 100644 --- a/tokio-timer/tests/interval.rs +++ b/tokio/tests/timer_interval.rs @@ -1,8 +1,8 @@ #![warn(rust_2018_idioms)] +use tokio::timer::*; use tokio_test::task::MockTask; use tokio_test::{assert_pending, assert_ready_eq, clock}; -use tokio_timer::*; use std::time::Duration; diff --git a/tokio-timer/tests/queue.rs b/tokio/tests/timer_queue.rs similarity index 99% rename from tokio-timer/tests/queue.rs rename to tokio/tests/timer_queue.rs index 4c3032294..7e1d7f6ac 100644 --- a/tokio-timer/tests/queue.rs +++ b/tokio/tests/timer_queue.rs @@ -1,8 +1,8 @@ #![warn(rust_2018_idioms)] +use tokio::timer::*; use tokio_test::task::MockTask; use tokio_test::{assert_ok, assert_pending, assert_ready, clock}; -use tokio_timer::*; use std::time::Duration; diff --git a/tokio/tests/timer.rs b/tokio/tests/timer_rt.rs similarity index 98% rename from tokio/tests/timer.rs rename to tokio/tests/timer_rt.rs index ca716ccbd..b677bb5c0 100644 --- a/tokio/tests/timer.rs +++ b/tokio/tests/timer_rt.rs @@ -1,5 +1,4 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "default")] use tokio::prelude::*; use tokio::timer::*; diff --git a/tokio-timer/tests/throttle.rs b/tokio/tests/timer_throttle.rs similarity index 93% rename from tokio-timer/tests/throttle.rs rename to tokio/tests/timer_throttle.rs index e8322e6d3..4d96e15ca 100644 --- a/tokio-timer/tests/throttle.rs +++ b/tokio/tests/timer_throttle.rs @@ -1,10 +1,9 @@ #![warn(rust_2018_idioms)] -#![cfg(feature = "async-traits")] -use tokio_sync::mpsc; +use tokio::sync::mpsc; +use tokio::timer::throttle::Throttle; use tokio_test::task::MockTask; use tokio_test::{assert_pending, assert_ready_eq, clock}; -use tokio_timer::throttle::Throttle; use futures_core::Stream; use std::time::Duration; diff --git a/tokio-timer/tests/timeout.rs b/tokio/tests/timer_timeout.rs similarity index 98% rename from tokio-timer/tests/timeout.rs rename to tokio/tests/timer_timeout.rs index 17b2812e3..9d704c6e2 100644 --- a/tokio-timer/tests/timeout.rs +++ b/tokio/tests/timer_timeout.rs @@ -1,11 +1,11 @@ #![warn(rust_2018_idioms)] -use tokio_sync::oneshot; +use tokio::sync::oneshot; +use tokio::timer::*; use tokio_test::task::MockTask; use tokio_test::{ assert_err, assert_pending, assert_ready, assert_ready_err, assert_ready_ok, clock, }; -use tokio_timer::*; use std::time::Duration;