diff --git a/.vscode/settings.json b/.vscode/settings.json index c00ccb459..9108568ea 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -67,6 +67,7 @@ "unordered_map": "cpp", "istream": "cpp", "thread": "cpp", - "utility": "cpp" + "utility": "cpp", + "streambuf": "cpp" } } diff --git a/src/common/StaggeredLogger.cxx b/src/common/StaggeredLogger.cxx index 71b341007..112c48d43 100644 --- a/src/common/StaggeredLogger.cxx +++ b/src/common/StaggeredLogger.cxx @@ -43,7 +43,8 @@ StaggeredLogger::StaggeredLogger(const string& message, Logger logger) myMaxIntervalFactor(9), myCurrentIntervalFactor(1), myCooldownTime(1000), - myTimer(new TimerManager()) + myTimer(new TimerManager()), + myTimerCallbackId(0) { if (logger) myLogger = logger; } @@ -148,14 +149,16 @@ void StaggeredLogger::startInterval() myLastIntervalStartTimestamp = now; myTimer->clear(myTimerId); - myTimerId = myTimer->setTimeout(std::bind(&StaggeredLogger::onTimerExpired, this), myCurrentIntervalSize); + myTimerId = myTimer->setTimeout(std::bind(&StaggeredLogger::onTimerExpired, this, ++myTimerCallbackId), myCurrentIntervalSize); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void StaggeredLogger::onTimerExpired() +void StaggeredLogger::onTimerExpired(uInt32 timerCallbackId) { std::lock_guard lock(myMutex); + if (timerCallbackId != myTimerCallbackId) return; + logLine(); myIsCurrentlyCollecting = false; diff --git a/src/common/StaggeredLogger.hxx b/src/common/StaggeredLogger.hxx index 6e6e93c06..8bcffcb9a 100644 --- a/src/common/StaggeredLogger.hxx +++ b/src/common/StaggeredLogger.hxx @@ -52,7 +52,7 @@ class StaggeredLogger { void _setLogger(Logger logger); - void onTimerExpired(); + void onTimerExpired(uInt32 timerId); void startInterval(); @@ -83,6 +83,11 @@ class StaggeredLogger { // our destructor. TimerManager *myTimer; TimerManager::TimerId myTimerId; + + // It is possible that the timer callback is running even after TimerManager::clear + // returns. This id is unique per timer and is used to return from the callback + // early in case the time is stale. + uInt32 myTimerCallbackId; }; #endif // STAGGERED_LOGGER