-
Notifications
You must be signed in to change notification settings - Fork 5.5k
scaled range timer: guard against queue deletion during timer fire #14799
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
Changes from 2 commits
6666db7
1514eec
bf84a7b
023d9ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -157,6 +157,33 @@ TEST_F(ScaledRangeTimerManagerTest, DisableWhileScalingMax) { | |
| simTime().advanceTimeAndRun(std::chrono::seconds(100), dispatcher_, Dispatcher::RunType::Block); | ||
| } | ||
|
|
||
| TEST_F(ScaledRangeTimerManagerTest, DisableOtherTimerInCallbackEmptiesQueue) { | ||
| ScaledRangeTimerManagerImpl manager(dispatcher_); | ||
|
|
||
| MockFunction<TimerCb> callback1; | ||
| auto timer1 = | ||
| manager.createTimer(AbsoluteMinimum(std::chrono::seconds(5)), callback1.AsStdFunction()); | ||
| MockFunction<TimerCb> callback2; | ||
| auto timer2 = | ||
| manager.createTimer(AbsoluteMinimum(std::chrono::seconds(5)), callback2.AsStdFunction()); | ||
|
|
||
| timer1->enableTimer(std::chrono::seconds(100)); | ||
| timer2->enableTimer(std::chrono::seconds(100)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since these timers are enabled for the same duration, they can fire in either order. Consider making timer1 fire in 95 seconds with an absolute minimum of 0.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need both timers to end up in the same queues so their durations should be the same. I think the solution is to do an advance of 5 seconds between the first enable and the second enable.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Either of those will work. The duration that matters is (max - min) which is (100 - 5) or (95 - 0) as adjusted. |
||
|
|
||
| simTime().advanceTimeAndRun(std::chrono::seconds(5), dispatcher_, Dispatcher::RunType::Block); | ||
|
|
||
| EXPECT_TRUE(timer1->enabled()); | ||
| EXPECT_TRUE(timer2->enabled()); | ||
|
|
||
| EXPECT_CALL(callback1, Call).WillOnce(Invoke([&]() { | ||
| timer2->disableTimer(); | ||
| timer2.reset(); | ||
| })); | ||
|
|
||
| // Run the dispatcher to make sure nothing happens when it's not supposed to. | ||
| simTime().advanceTimeAndRun(std::chrono::seconds(100), dispatcher_, Dispatcher::RunType::Block); | ||
| } | ||
|
|
||
| TEST_F(ScaledRangeTimerManagerTest, DisableWithZeroMinTime) { | ||
| ScaledRangeTimerManagerImpl manager(dispatcher_); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So processing_timers_ needs to be per queue since otherwise the queue not empty invariant would not hold if a timer from queue A removes a timer from queue B. It would be good to also cover that case in tests.
Also, is there code somewhere that verifies the invariant that all active queues are non-empty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe there is currently. The number of queues and sizes is not currently exposed. I'm okay to keep this PR focused on the bugfix and add additional testing in a follow-on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
023d9ec adds a test for cancelling a timer from a different queue in the context of a timer callback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc: @asraa
@akonradi Please do followup. Regarding ASSERTs, I think failing this one will result in a crash in the next line.
envoy/source/common/event/scaled_range_timer_manager_impl.cc
Line 244 in bf84a7b