From eec26c21d5a812f4c6bbeafea1384339eab6e907 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Tue, 17 Aug 2021 12:51:53 +0000 Subject: [PATCH 1/2] time: don't panic when Instant is not monotonic --- tokio/src/time/driver/mod.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tokio/src/time/driver/mod.rs b/tokio/src/time/driver/mod.rs index 37d2231c34f..ce65645c38a 100644 --- a/tokio/src/time/driver/mod.rs +++ b/tokio/src/time/driver/mod.rs @@ -205,7 +205,15 @@ where fn park_internal(&mut self, limit: Option) -> Result<(), P::Error> { let mut lock = self.handle.get().state.lock(); - assert!(!self.handle.is_shutdown()); + if now < lock.elapsed { + // Time went backwards! This normally shouldn't happen as the Rust language + // guarantees that an Instant is monotonic, but can happen when running + // Linux in a VM on a Windows host due to std incorrectly trusting the + // hardware clock to be monotonic. + // + // See for more information. + now = lock.elapsed; + } let next_wake = lock.wheel.next_expiration_time(); lock.next_wake = From dac9be07bfbafc46c779b0d0b18990b0e6905045 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Tue, 17 Aug 2021 13:04:44 +0000 Subject: [PATCH 2/2] fix copy paste mistake --- tokio/src/time/driver/mod.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tokio/src/time/driver/mod.rs b/tokio/src/time/driver/mod.rs index ce65645c38a..f611fbb9c8e 100644 --- a/tokio/src/time/driver/mod.rs +++ b/tokio/src/time/driver/mod.rs @@ -205,15 +205,7 @@ where fn park_internal(&mut self, limit: Option) -> Result<(), P::Error> { let mut lock = self.handle.get().state.lock(); - if now < lock.elapsed { - // Time went backwards! This normally shouldn't happen as the Rust language - // guarantees that an Instant is monotonic, but can happen when running - // Linux in a VM on a Windows host due to std incorrectly trusting the - // hardware clock to be monotonic. - // - // See for more information. - now = lock.elapsed; - } + assert!(!self.handle.is_shutdown()); let next_wake = lock.wheel.next_expiration_time(); lock.next_wake = @@ -296,13 +288,21 @@ impl Handle { self.process_at_time(now) } - pub(self) fn process_at_time(&self, now: u64) { + pub(self) fn process_at_time(&self, mut now: u64) { let mut waker_list: [Option; 32] = Default::default(); let mut waker_idx = 0; let mut lock = self.get().lock(); - assert!(now >= lock.elapsed); + if now < lock.elapsed { + // Time went backwards! This normally shouldn't happen as the Rust language + // guarantees that an Instant is monotonic, but can happen when running + // Linux in a VM on a Windows host due to std incorrectly trusting the + // hardware clock to be monotonic. + // + // See for more information. + now = lock.elapsed; + } while let Some(entry) = lock.wheel.poll(now) { debug_assert!(unsafe { entry.is_pending() });