Commit 816901d6 authored by Juho Snellman's avatar Juho Snellman

Fix bug with timer rescheduling

- Not enough to just redefine the relink() method, need to
  also use it...
parent ac748567
......@@ -43,22 +43,28 @@ bool test_single_timer_no_hierarchy() {
int count = 0;
TimerEvent<Callback> timer([&count] () { ++count; });
// Unscheduled timer does nothing.
timers.advance(10);
EXPECT_INTEQ(count, 0);
EXPECT(!timer.active());
// Schedule timer, should trigger at right time.
timers.schedule(&timer, 5);
EXPECT(timer.active());
timers.advance(10);
timers.advance(5);
EXPECT_INTEQ(count, 1);
timers.advance(10);
// Only trigger once, not repeatedly (even if wheel wraps
// around).
timers.advance(256);
EXPECT_INTEQ(count, 1);
// ... unless, of course, the timer gets scheduled again.
timers.schedule(&timer, 5);
timers.advance(10);
timers.advance(5);
EXPECT_INTEQ(count, 2);
// Canceled timers don't run.
timers.schedule(&timer, 5);
timer.cancel();
EXPECT(!timer.active());
......@@ -71,6 +77,15 @@ bool test_single_timer_no_hierarchy() {
timers.advance(10);
EXPECT_INTEQ(count, 3);
// Timers that are scheduled multiple times only run at the last
// scheduled tick.
timers.schedule(&timer, 5);
timers.schedule(&timer, 10);
timers.advance(5);
EXPECT_INTEQ(count, 3);
timers.advance(5);
EXPECT_INTEQ(count, 4);
return true;
}
......
......@@ -153,8 +153,18 @@ public:
size_t slot_index = (now_ + delta) & MASK;
auto slot = &slots_[slot_index];
if (event->active()) {
event->relink(slot);
} else {
slot->push_event(event);
}
}
// Return the current tick value. Note that if the timers advance by
// multiple ticks during a single call to advance(), the value of now()
// will be the tick on which the timer was first run. Not the tick that
// the timer eventually will advance to.
const Tick& now() const { return now_; }
private:
TimerWheel(const TimerWheel& other) = delete;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment