diff --git a/tokio/Cargo.toml b/tokio/Cargo.toml index 12a8c698570..8a64b00bee0 100644 --- a/tokio/Cargo.toml +++ b/tokio/Cargo.toml @@ -83,7 +83,7 @@ signal = [ ] sync = [] test-util = ["rt", "sync", "time"] -time = [] +time = ["web-time"] [dependencies] tokio-macros = { version = "~2.4.0", path = "../tokio-macros", optional = true } @@ -98,6 +98,9 @@ parking_lot = { version = "0.12.0", optional = true } [target.'cfg(not(target_family = "wasm"))'.dependencies] socket2 = { version = "0.5.5", optional = true, features = [ "all" ] } +[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies] +web-time = { version = "1", optional = true } + # Currently unstable. The API exposed by these features may be broken at any time. # Requires `--cfg tokio_unstable` to enable. [target.'cfg(tokio_unstable)'.dependencies] diff --git a/tokio/src/macros/cfg.rs b/tokio/src/macros/cfg.rs index 8a72476f7c4..e64e2d19b07 100644 --- a/tokio/src/macros/cfg.rs +++ b/tokio/src/macros/cfg.rs @@ -603,3 +603,21 @@ macro_rules! cfg_is_wasm_not_wasi { )* } } + +macro_rules! cfg_wasm_unknown { + ($($item:item)*) => { + $( + #[cfg(all(target_family = "wasm", target_os = "unknown"))] + $item + )* + } +} + +macro_rules! cfg_not_wasm_unknown { + ($($item:item)*) => { + $( + #[cfg(not(all(target_family = "wasm", target_os = "unknown")))] + $item + )* + } +} diff --git a/tokio/src/time/clock.rs b/tokio/src/time/clock.rs index 50884f972fa..7024ce52a3d 100644 --- a/tokio/src/time/clock.rs +++ b/tokio/src/time/clock.rs @@ -7,13 +7,13 @@ //! configurable. cfg_not_test_util! { - use crate::time::{Instant}; + use crate::time::{Instant, InstantInner}; #[derive(Debug, Clone)] pub(crate) struct Clock {} pub(crate) fn now() -> Instant { - Instant::from_std(std::time::Instant::now()) + Instant::from_std(InstantInner::now()) } impl Clock { @@ -28,7 +28,7 @@ cfg_not_test_util! { } cfg_test_util! { - use crate::time::{Duration, Instant}; + use crate::time::{Duration, Instant, InstantInner}; use crate::loom::sync::Mutex; use crate::loom::sync::atomic::Ordering; use std::sync::atomic::AtomicBool as StdAtomicBool; @@ -82,10 +82,10 @@ cfg_test_util! { enable_pausing: bool, /// Instant to use as the clock's base instant. - base: std::time::Instant, + base: InstantInner, /// Instant at which the clock was last unfrozen. - unfrozen: Option, + unfrozen: Option, /// Number of `inhibit_auto_advance` calls still in effect. auto_advance_inhibit_count: usize, @@ -159,7 +159,7 @@ cfg_test_util! { return Err("time is not frozen"); } - inner.unfrozen = Some(std::time::Instant::now()); + inner.unfrozen = Some(InstantInner::now()); Ok(()) }); } @@ -211,14 +211,14 @@ cfg_test_util! { /// Returns the current instant, factoring in frozen time. pub(crate) fn now() -> Instant { if !DID_PAUSE_CLOCK.load(Ordering::Acquire) { - return Instant::from_std(std::time::Instant::now()); + return Instant::from_std(InstantInner::now()); } with_clock(|maybe_clock| { Ok(if let Some(clock) = maybe_clock { clock.now() } else { - Instant::from_std(std::time::Instant::now()) + Instant::from_std(InstantInner::now()) }) }) } @@ -227,7 +227,7 @@ cfg_test_util! { /// Returns a new `Clock` instance that uses the current execution context's /// source of time. pub(crate) fn new(enable_pausing: bool, start_paused: bool) -> Clock { - let now = std::time::Instant::now(); + let now = InstantInner::now(); let clock = Clock { inner: Mutex::new(Inner { diff --git a/tokio/src/time/instant.rs b/tokio/src/time/instant.rs index 14cf6e567b5..a909ac9747a 100644 --- a/tokio/src/time/instant.rs +++ b/tokio/src/time/instant.rs @@ -4,6 +4,14 @@ use std::fmt; use std::ops; use std::time::Duration; +cfg_wasm_unknown! { + pub(crate) type InstantInner = web_time::Instant; +} + +cfg_not_wasm_unknown! { + pub(crate) type InstantInner = std::time::Instant; +} + /// A measurement of a monotonically nondecreasing clock. /// Opaque and useful only with `Duration`. /// @@ -32,7 +40,7 @@ use std::time::Duration; /// take advantage of `time::pause()` and `time::advance()`. #[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] pub struct Instant { - std: std::time::Instant, + std: InstantInner, } impl Instant { @@ -50,7 +58,7 @@ impl Instant { } /// Create a `tokio::time::Instant` from a `std::time::Instant`. - pub fn from_std(std: std::time::Instant) -> Instant { + pub fn from_std(std: InstantInner) -> Instant { Instant { std } } @@ -63,7 +71,7 @@ impl Instant { } /// Convert the value into a `std::time::Instant`. - pub fn into_std(self) -> std::time::Instant { + pub fn into_std(self) -> InstantInner { self.std } @@ -150,14 +158,14 @@ impl Instant { } } -impl From for Instant { - fn from(time: std::time::Instant) -> Instant { +impl From for Instant { + fn from(time: InstantInner) -> Instant { Instant::from_std(time) } } -impl From for std::time::Instant { - fn from(time: Instant) -> std::time::Instant { +impl From for InstantInner { + fn from(time: Instant) -> InstantInner { time.into_std() } } @@ -188,7 +196,7 @@ impl ops::Sub for Instant { type Output = Instant; fn sub(self, rhs: Duration) -> Instant { - Instant::from_std(std::time::Instant::sub(self.std, rhs)) + Instant::from_std(InstantInner::sub(self.std, rhs)) } } @@ -206,10 +214,10 @@ impl fmt::Debug for Instant { #[cfg(not(feature = "test-util"))] mod variant { - use super::Instant; + use super::{Instant, InstantInner}; pub(super) fn now() -> Instant { - Instant::from_std(std::time::Instant::now()) + Instant::from_std(InstantInner::now()) } } diff --git a/tokio/src/time/mod.rs b/tokio/src/time/mod.rs index c0cd7c62856..91011886e33 100644 --- a/tokio/src/time/mod.rs +++ b/tokio/src/time/mod.rs @@ -96,6 +96,7 @@ mod instant; pub use self::instant::Instant; mod interval; +pub(crate) use instant::InstantInner; pub use interval::{interval, interval_at, Interval, MissedTickBehavior}; mod sleep;