From 8f81e0814bd121683ebdfa21b494d1b77fb36403 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Wed, 29 Apr 2026 07:26:57 +0200 Subject: [PATCH] time: avoid stack overflow in runtime constructor (#8093) --- tokio/src/runtime/time/wheel/mod.rs | 8 ++++++-- tokio/src/runtime/time_alt/wheel/mod.rs | 8 +++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/tokio/src/runtime/time/wheel/mod.rs b/tokio/src/runtime/time/wheel/mod.rs index c0c51ef74..a58954c52 100644 --- a/tokio/src/runtime/time/wheel/mod.rs +++ b/tokio/src/runtime/time/wheel/mod.rs @@ -5,7 +5,7 @@ mod level; pub(crate) use self::level::Expiration; use self::level::Level; -use std::{array, ptr::NonNull}; +use std::ptr::NonNull; use super::entry::STATE_DEREGISTERED; use super::EntryList; @@ -50,9 +50,13 @@ pub(super) const MAX_DURATION: u64 = (1 << (6 * NUM_LEVELS)) - 1; impl Wheel { /// Creates a new timing wheel. pub(crate) fn new() -> Wheel { + let mut levels = Vec::with_capacity(NUM_LEVELS); + for i in 0..NUM_LEVELS { + levels.push(Level::new(i)); + } Wheel { elapsed: 0, - levels: Box::new(array::from_fn(Level::new)), + levels: levels.into_boxed_slice().try_into().unwrap(), pending: EntryList::new(), } } diff --git a/tokio/src/runtime/time_alt/wheel/mod.rs b/tokio/src/runtime/time_alt/wheel/mod.rs index 324704e9c..a17ed5b85 100644 --- a/tokio/src/runtime/time_alt/wheel/mod.rs +++ b/tokio/src/runtime/time_alt/wheel/mod.rs @@ -5,8 +5,6 @@ use self::level::Level; use super::cancellation_queue::Sender; use super::{EntryHandle, EntryList, WakeQueue}; -use std::array; - /// Hashed timing wheel implementation. /// /// See [`Driver`] documentation for some implementation notes. @@ -41,9 +39,13 @@ pub(super) const MAX_DURATION: u64 = (1 << (6 * NUM_LEVELS)) - 1; impl Wheel { /// Creates a new timing wheel. pub(crate) fn new() -> Wheel { + let mut levels = Vec::with_capacity(NUM_LEVELS); + for i in 0..NUM_LEVELS { + levels.push(Level::new(i)); + } Wheel { elapsed: 0, - levels: Box::new(array::from_fn(Level::new)), + levels: levels.into_boxed_slice().try_into().unwrap(), } }