Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address issue 2473 #2587

Merged
merged 3 commits into from
Jul 26, 2020
Merged

Address issue 2473 #2587

merged 3 commits into from
Jul 26, 2020

Conversation

fegies
Copy link
Contributor

@fegies fegies commented Jun 5, 2020

Motivation

Resetting expired timers can cause panics (see #2473)

Solution

Add an additional check in the remove function fixes this issue.

Please feel free to discard the second commit if you think it is incorrect / correct me if I put the test in the wrong location.

@Darksonn Darksonn added A-tokio Area: The main tokio crate C-maintenance Category: PRs that clean code up or issues documenting cleanup. M-time Module: tokio/time labels Jun 5, 2020
@Darksonn
Copy link
Contributor

Can you please merge master? That should fix CI.

@Darksonn Darksonn requested a review from carllerche June 10, 2020 20:54
This test demonstrates a panic that occurs when the user inserts an
item with an instant in the past, and then tries to reset the timeout
using the returned key
@fegies
Copy link
Contributor Author

fegies commented Jun 11, 2020

Rebased onto master

@jxs jxs requested a review from Darksonn June 12, 2020 11:20
Copy link
Contributor

@Darksonn Darksonn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems wrong. The DelayQueue should not try to remove things from the wheel that are not in the wheel. It seems like a special case in reset_at would be more appropriate, similar to what DelayQueue::remove does:

// Special case the `expired` queue
if self.slab[key.index].expired {
self.expired.remove(&key.index, &mut self.slab);
} else {
self.wheel.remove(&key.index, &mut self.slab);
}

That said, I'm not sure and spent a long time staring at this trying to figure out what the variables really mean.

@jxs
Copy link
Member

jxs commented Jun 15, 2020

The DelayQueue should not try to remove things from the wheel that are not in the wheel.

ah sorry, I thought it was supposed to as the doc states the function panics if key is not contained by the queue.

@Darksonn
Copy link
Contributor

Well, the DelayQueue distributes the timeouts into two collections, namely wheel and expired, so just because the key is in the DelayQueue, that does not mean that it is also in the wheel.

@fegies
Copy link
Contributor Author

fegies commented Jun 15, 2020

Well, the DelayQueue distributes the timeouts into two collections, namely wheel and expired, so just because the key is in the DelayQueue, that does not mean that it is also in the wheel.

Which is the source of the problem causing the panic.

I can move the test to reset_at if you think this is more appropriate (should work either way)

@Darksonn
Copy link
Contributor

Yeah, I think it is better to have DelayQueue use the api as exposed by the wheel, and have the check in reset_at instead.

Trying to remove an already expired Timer Wheel entry (called by
DelayQueue.reset()) causes panics in some cases as described in (tokio-rs#2573)

This prevents this panic by removing the item from the expired queue and
not the wheel in these cases
@fegies
Copy link
Contributor Author

fegies commented Jun 15, 2020

Replaced the fix commit with a check in the DelayQueue

@Darksonn Darksonn merged commit 7f29acd into tokio-rs:master Jul 26, 2020
@Darksonn Darksonn mentioned this pull request Nov 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-maintenance Category: PRs that clean code up or issues documenting cleanup. M-time Module: tokio/time
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants