Bug 1726177: For repeating precise, keep the cadence when we finish firing late. r=xpcom-reviewers,nika,jesup

Covers the case where we finish late because the callback took a long time,
and the case where we fired really late (eg; because of sleep).

Differential Revision: https://phabricator.services.mozilla.com/D123814
This commit is contained in:
Byron Campen [:bwc] 2021-09-03 21:59:00 +00:00
Родитель 4aee661e93
Коммит f0dde51af4
1 изменённых файлов: 17 добавлений и 5 удалений

Просмотреть файл

@ -595,9 +595,9 @@ void nsTimerImpl::Fire(int32_t aGeneration) {
AUTO_PROFILER_LABEL("nsTimerImpl::Fire", OTHER);
TimeStamp now = TimeStamp::Now();
TimeStamp fireTime = TimeStamp::Now();
if (MOZ_LOG_TEST(GetTimerLog(), LogLevel::Debug)) {
TimeDuration delta = now - oldTimeout;
TimeDuration delta = fireTime - oldTimeout;
int32_t d = delta.ToMilliseconds(); // delta in ms
sDeltaSum += abs(d);
sDeltaSumSquared += double(d) * double(d);
@ -626,14 +626,26 @@ void nsTimerImpl::Fire(int32_t aGeneration) {
[&](const FuncCallback& f) { f.mFunc(mITimer, f.mClosure); },
[&](const ClosureCallback& c) { c.mFunc(mITimer); });
TimeStamp now = TimeStamp::Now();
MutexAutoLock lock(mMutex);
if (aGeneration == mGeneration) {
if (IsRepeating()) {
// Repeating timer has not been re-init or canceled; reschedule
if (IsSlack()) {
mTimeout = TimeStamp::Now() + mDelay;
mTimeout = now + mDelay;
} else {
mTimeout = mTimeout + mDelay;
if (mDelay) {
// If we are late enough finishing the callback that we have missed
// some firings, do not attempt to play catchup, just get back on the
// cadence we're supposed to maintain.
unsigned missedFirings =
static_cast<unsigned>((now - mTimeout) / mDelay);
mTimeout += mDelay * (missedFirings + 1);
} else {
// Can we stop allowing repeating timers with delay 0?
mTimeout = now;
}
}
gThreadWrapper.AddTimer(this, lock);
} else {
@ -648,7 +660,7 @@ void nsTimerImpl::Fire(int32_t aGeneration) {
MOZ_LOG(GetTimerLog(), LogLevel::Debug,
("[this=%p] Took %fms to fire timer callback\n", this,
(TimeStamp::Now() - now).ToMilliseconds()));
(now - fireTime).ToMilliseconds()));
}
// See the big comment above GetTimerFiringsLog() to understand this code.