time: do not panic on Interval::poll_tick if the sum of the timeout and period overflow#6487
time: do not panic on Interval::poll_tick if the sum of the timeout and period overflow#6487
Conversation
if the sum of the timeout and period overflow
|
Thanks. Can you add a test to |
|
Using fn saturating_add(lhs: Instant, rhs: Duration) -> Instant {
if let Some(out) = lhs.checked_add(rhs) {
out
} else {
saturate(lhs)
}
}
#[cold]
fn saturate(mut instant: Instant) -> Instant {
let mut secs = 1_u64 << 63;
while secs > 0 {
if let Some(incr) = instant.checked_add(Duration::from_secs(secs)) {
instant = incr;
}
secs >>= 1;
}
let mut nanos = 1_u64 << 30;
while nanos > 0 {
if let Some(incr) = instant.checked_add(Duration::from_nanos(nanos)) {
instant = incr;
}
nanos >>= 1;
}
instant
}see #https://github.com/b3t33/tokio/commit/2e9743b74d097c14ec3223f909d12daa12f8532a for a possible integration into |
|
|
|
Is it a good idea to add some explanation about this overflow behavior on the |
|
I don't think it's necessary, but it also doesn't hurt to mention that. |
|
thanks Alice, added a test |
| timeout + self.period | ||
| timeout | ||
| .checked_add(self.period) | ||
| .unwrap_or(Instant::far_future()) |
There was a problem hiding this comment.
Drive-by review: this may make sense as unwrap_or_else 🤔
Darksonn
left a comment
There was a problem hiding this comment.
I've verified that the test does fail without this change. Thanks!
|
It seems there is a clippy failure. |
|
Stress test is failing, but seems unrelated |
|
Yes, see the CI issue above. |
Motivation
when calling tokio::time::interval(Duration::MAX) runtime panics with:
see reproduction here. Panic happens when adding
timeoutto to thedelaydeadline.Solution
This PR addresses the panic by calling
Instant::checked_addfalling back toInstant::far_future()when it overflows. If needed I can add a test for it and update the documentation mentioning this behaviour.Thanks!