Commit b5759618 authored by Keith Birney's avatar Keith Birney Committed by Facebook Github Bot

Use consistent time_point in cascadeTimers

Summary: This fixes a timing issue that has been observed in rare cases under very heavy load.

Differential Revision: D18875069

fbshipit-source-id: cd47abfbd01c10e2568693f876dd3e6c2cb3bb24
parent 564a32e6
......@@ -205,17 +205,19 @@ void HHWheelTimerBase<Duration>::scheduleTimeout(Callback* callback) {
}
template <class Duration>
bool HHWheelTimerBase<Duration>::cascadeTimers(int bucket, int tick) {
bool HHWheelTimerBase<Duration>::cascadeTimers(
int bucket,
int tick,
const std::chrono::steady_clock::time_point curTime) {
CallbackList cbs;
cbs.swap(buckets_[bucket][tick]);
auto now = getCurTime();
auto nextTick = calcNextTick(now);
auto nextTick = calcNextTick(curTime);
while (!cbs.empty()) {
auto* cb = &cbs.front();
cbs.pop_front();
scheduleTimeoutImpl(
cb,
nextTick + timeToWheelTicks(cb->getTimeRemaining(now)),
nextTick + timeToWheelTicks(cb->getTimeRemaining(curTime)),
expireTick_,
nextTick);
}
......@@ -231,7 +233,8 @@ void HHWheelTimerBase<Duration>::scheduleTimeoutInternal(Duration timeout) {
template <class Duration>
void HHWheelTimerBase<Duration>::timeoutExpired() noexcept {
auto nextTick = calcNextTick();
auto curTime = getCurTime();
auto nextTick = calcNextTick(curTime);
// If the last smart pointer for "this" is reset inside the callback's
// timeoutExpired(), then the guard will detect that it is time to bail from
......@@ -256,9 +259,11 @@ void HHWheelTimerBase<Duration>::timeoutExpired() noexcept {
if (idx == 0) {
// Cascade timers
if (cascadeTimers(1, (expireTick_ >> WHEEL_BITS) & WHEEL_MASK) &&
cascadeTimers(2, (expireTick_ >> (2 * WHEEL_BITS)) & WHEEL_MASK)) {
cascadeTimers(3, (expireTick_ >> (3 * WHEEL_BITS)) & WHEEL_MASK);
if (cascadeTimers(1, (expireTick_ >> WHEEL_BITS) & WHEEL_MASK, curTime) &&
cascadeTimers(
2, (expireTick_ >> (2 * WHEEL_BITS)) & WHEEL_MASK, curTime)) {
cascadeTimers(
3, (expireTick_ >> (3 * WHEEL_BITS)) & WHEEL_MASK, curTime);
}
}
......
......@@ -299,7 +299,10 @@ class HHWheelTimerBase : private folly::AsyncTimeout,
return t.count() / interval_.count();
}
bool cascadeTimers(int bucket, int tick);
bool cascadeTimers(
int bucket,
int tick,
std::chrono::steady_clock::time_point curTime);
void scheduleTimeoutInternal(Duration timeout);
int64_t expireTick_;
......
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