From a8844ce8e6351055b793a08ed5d35c64dd457f87 Mon Sep 17 00:00:00 2001 From: Weijia Jiang Date: Tue, 16 Jul 2024 21:25:59 +0800 Subject: [PATCH] time: fix race condition leading to lost timers (#6683) --- tokio/src/runtime/time/mod.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tokio/src/runtime/time/mod.rs b/tokio/src/runtime/time/mod.rs index f3174b33682..0e4c995dcd0 100644 --- a/tokio/src/runtime/time/mod.rs +++ b/tokio/src/runtime/time/mod.rs @@ -190,11 +190,13 @@ impl Driver { assert!(!handle.is_shutdown()); // Finds out the min expiration time to park. - let expiration_time = (0..rt_handle.time().inner.get_shard_size()) - .filter_map(|id| { - let lock = rt_handle.time().inner.lock_sharded_wheel(id); - lock.next_expiration_time() - }) + let locks = (0..rt_handle.time().inner.get_shard_size()) + .map(|id| rt_handle.time().inner.lock_sharded_wheel(id)) + .collect::>(); + + let expiration_time = locks + .iter() + .filter_map(|lock| lock.next_expiration_time()) .min(); rt_handle @@ -203,6 +205,9 @@ impl Driver { .next_wake .store(next_wake_time(expiration_time)); + // Safety: After updating the `next_wake`, we drop all the locks. + drop(locks); + match expiration_time { Some(when) => { let now = handle.time_source.now(rt_handle.clock());