From 925c614c89d0a26777a334612e2ed6ad0e7935c3 Mon Sep 17 00:00:00 2001 From: Alex Bakon Date: Tue, 19 Aug 2025 07:42:55 -0400 Subject: [PATCH] time: reduce the generated code size of `Timeout::poll` (#7535) --- tokio/src/time/timeout.rs | 48 ++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/tokio/src/time/timeout.rs b/tokio/src/time/timeout.rs index e7fbe75dc..ce4bf16d5 100644 --- a/tokio/src/time/timeout.rs +++ b/tokio/src/time/timeout.rs @@ -203,26 +203,32 @@ where return Poll::Ready(Ok(v)); } - let has_budget_now = coop::has_budget_remaining(); - - let delay = me.delay; - - let poll_delay = || -> Poll { - match delay.poll(cx) { - Poll::Ready(()) => Poll::Ready(Err(Elapsed::new())), - Poll::Pending => Poll::Pending, - } - }; - - if let (true, false) = (had_budget_before, has_budget_now) { - // if it is the underlying future that exhausted the budget, we poll - // the `delay` with an unconstrained one. This prevents pathological - // cases where the underlying future always exhausts the budget and - // we never get a chance to evaluate whether the timeout was hit or - // not. - coop::with_unconstrained(poll_delay) - } else { - poll_delay() - } + poll_delay(had_budget_before, me.delay, cx).map(Err) + } +} + +// The T-invariant portion of Timeout::::poll. Pulling this out reduces the +// amount of code that gets duplicated during monomorphization. +fn poll_delay( + had_budget_before: bool, + delay: Pin<&mut Sleep>, + cx: &mut task::Context<'_>, +) -> Poll { + let delay_poll = || match delay.poll(cx) { + Poll::Ready(()) => Poll::Ready(Elapsed::new()), + Poll::Pending => Poll::Pending, + }; + + let has_budget_now = coop::has_budget_remaining(); + + if let (true, false) = (had_budget_before, has_budget_now) { + // if it is the underlying future that exhausted the budget, we poll + // the `delay` with an unconstrained one. This prevents pathological + // cases where the underlying future always exhausts the budget and + // we never get a chance to evaluate whether the timeout was hit or + // not. + coop::with_unconstrained(delay_poll) + } else { + delay_poll() } }