Bug 1363829 P16 Allow setTimeout() to fire early based on nsIThread::GetAllowedEarlyFiringMicroseconds(). r=ehsan

This commit is contained in:
Ben Kelly 2017-05-31 17:13:20 -07:00
Родитель 3c709a6f61
Коммит ded5801245
2 изменённых файлов: 16 добавлений и 5 удалений

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

@ -26,7 +26,7 @@ TimeoutExecutor::ScheduleImmediate(const TimeStamp& aDeadline,
{
MOZ_DIAGNOSTIC_ASSERT(mDeadline.IsNull());
MOZ_DIAGNOSTIC_ASSERT(mMode == Mode::None);
MOZ_DIAGNOSTIC_ASSERT(aDeadline <= aNow);
MOZ_DIAGNOSTIC_ASSERT(aDeadline <= (aNow + mAllowedEarlyFiringTime));
nsresult rv =
mOwner->EventTarget()->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
@ -44,13 +44,17 @@ TimeoutExecutor::ScheduleDelayed(const TimeStamp& aDeadline,
{
MOZ_DIAGNOSTIC_ASSERT(mDeadline.IsNull());
MOZ_DIAGNOSTIC_ASSERT(mMode == Mode::None);
MOZ_DIAGNOSTIC_ASSERT(aDeadline > aNow);
MOZ_DIAGNOSTIC_ASSERT(aDeadline > (aNow + mAllowedEarlyFiringTime));
nsresult rv = NS_OK;
if (!mTimer) {
mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t earlyMicros = 0;
MOZ_ALWAYS_SUCCEEDS(mTimer->GetAllowedEarlyFiringMicroseconds(&earlyMicros));
mAllowedEarlyFiringTime = TimeDuration::FromMicroseconds(earlyMicros);
}
// Always call Cancel() in case we are re-using a timer. Otherwise
@ -97,7 +101,7 @@ TimeoutExecutor::Schedule(const TimeStamp& aDeadline)
// Schedule an immediate runnable if the desired deadline has passed
// or is slightly in the future. This is similar to how nsITimer will
// fire timers early based on the interval resolution.
if (aDeadline <= now) {
if (aDeadline <= (now + mAllowedEarlyFiringTime)) {
return ScheduleImmediate(aDeadline, now);
}
@ -140,8 +144,9 @@ TimeoutExecutor::MaybeExecute()
// and proceed. If there are no timers ready we will get rescheduled
// by TimeoutManager.
TimeStamp now(TimeStamp::Now());
if (deadline > now) {
deadline = now;
TimeStamp limit = now + mAllowedEarlyFiringTime;
if (deadline > limit) {
deadline = limit;
}
Cancel();

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

@ -22,6 +22,12 @@ class TimeoutExecutor final : public nsIRunnable
nsCOMPtr<nsITimer> mTimer;
TimeStamp mDeadline;
// Limits how far we allow timers to fire into the future from their
// deadline. Starts off at zero, but is then adjusted when we start
// using nsITimer. The nsITimer implementation may sometimes fire
// early and we should allow that to minimize additional wakeups.
TimeDuration mAllowedEarlyFiringTime;
// The TimeoutExecutor is repeatedly scheduled by the TimeoutManager
// to fire for the next soonest Timeout. Since the executor is re-used
// it needs to handle switching between a few states.