Bug 1339909 - More eagarly clear throttle tracking timer. r=bkelly
authorAndreas Farre <farre@mozilla.com>
Tue, 25 Apr 2017 05:20:00 -0400
changeset 403220 6fbda056532ebc49e993d169799e2b19205b36ba
parent 403219 27114f4cd6e7a306139d59a9b959e0183e5613ab
child 403221 3c182ffc4e7655e529541d06c4b6b598c3373d6a
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly
bugs1339909
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1339909 - More eagarly clear throttle tracking timer. r=bkelly Clear the throttle tracking timer in ClearAllTimeouts. Also clear it in Suspend, and if mThrottleTrackingTimeouts isn't set restart the timer if the document hasn't loaded.
dom/base/TimeoutManager.cpp
dom/base/TimeoutManager.h
dom/base/nsGlobalWindow.cpp
dom/base/nsPIDOMWindow.h
--- a/dom/base/TimeoutManager.cpp
+++ b/dom/base/TimeoutManager.cpp
@@ -1013,16 +1013,21 @@ TimeoutManager::Timeouts::ResetTimersFor
 void
 TimeoutManager::ClearAllTimeouts()
 {
   bool seenRunningTimeout = false;
 
   MOZ_LOG(gLog, LogLevel::Debug,
           ("ClearAllTimeouts(TimeoutManager=%p)\n", this));
 
+  if (mThrottleTrackingTimeoutsTimer) {
+    mThrottleTrackingTimeoutsTimer->Cancel();
+    mThrottleTrackingTimeoutsTimer = nullptr;
+  }
+
   ForEachUnorderedTimeout([&](Timeout* aTimeout) {
     /* If RunTimeout() is higher up on the stack for this
        window, e.g. as a result of document.write from a timeout,
        then we need to reset the list insertion point for
        newly-created timeouts in case the user adds a timeout,
        before we pop the stack back to RunTimeout. */
     if (mRunningTimeout == aTimeout) {
       seenRunningTimeout = true;
@@ -1118,16 +1123,21 @@ TimeoutManager::UnmarkGrayTimers()
 }
 
 void
 TimeoutManager::Suspend()
 {
   MOZ_LOG(gLog, LogLevel::Debug,
           ("Suspend(TimeoutManager=%p)\n", this));
 
+  if (mThrottleTrackingTimeoutsTimer) {
+    mThrottleTrackingTimeoutsTimer->Cancel();
+    mThrottleTrackingTimeoutsTimer = nullptr;
+  }
+
   ForEachUnorderedTimeout([](Timeout* aTimeout) {
     // Leave the timers with the current time remaining.  This will
     // cause the timers to potentially fire when the window is
     // Resume()'d.  Time effectively passes while suspended.
 
     // Drop the XPCOM timer; we'll reschedule when restoring the state.
     if (aTimeout->mTimer) {
       aTimeout->mTimer->Cancel();
@@ -1141,16 +1151,23 @@ TimeoutManager::Suspend()
 }
 
 void
 TimeoutManager::Resume()
 {
   MOZ_LOG(gLog, LogLevel::Debug,
           ("Resume(TimeoutManager=%p)\n", this));
 
+  // When Suspend() has been called after IsDocumentLoaded(), but the
+  // throttle tracking timer never managed to fire, start the timer
+  // again.
+  if (mWindow.AsInner()->IsDocumentLoaded() && !mThrottleTrackingTimeouts) {
+    MaybeStartThrottleTrackingTimout();
+  }
+
   TimeStamp now = TimeStamp::Now();
   DebugOnly<bool> _seenDummyTimeout = false;
 
   ForEachUnorderedTimeout([&](Timeout* aTimeout) {
     // There's a chance we're being called with RunTimeout on the stack in which
     // case we have a dummy timeout in the list that *must not* be resumed. It
     // can be identified by a null mWindow.
     if (!aTimeout->mWindow) {
@@ -1307,16 +1324,22 @@ TimeoutManager::StartThrottlingTrackingT
   MOZ_DIAGNOSTIC_ASSERT(!mThrottleTrackingTimeouts);
   mThrottleTrackingTimeouts = true;
   mThrottleTrackingTimeoutsTimer = nullptr;
 }
 
 void
 TimeoutManager::OnDocumentLoaded()
 {
+  MaybeStartThrottleTrackingTimout();
+}
+
+void
+TimeoutManager::MaybeStartThrottleTrackingTimout()
+{
   if (gTrackingTimeoutThrottlingDelay <= 0) {
     return;
   }
 
   MOZ_DIAGNOSTIC_ASSERT(!mThrottleTrackingTimeouts);
 
   MOZ_LOG(gLog, LogLevel::Debug,
           ("TimeoutManager %p delaying tracking timeout throttling by %dms\n",
--- a/dom/base/TimeoutManager.h
+++ b/dom/base/TimeoutManager.h
@@ -112,16 +112,17 @@ public:
   {
     if (!mNormalTimeouts.ForEachAbortable(c)) {
       mTrackingTimeouts.ForEachAbortable(c);
     }
   }
 
 private:
   nsresult ResetTimersForThrottleReduction(int32_t aPreviousThrottleDelayMS);
+  void MaybeStartThrottleTrackingTimout();
 
 private:
   struct Timeouts {
     Timeouts()
       : mTimeoutInsertionPoint(nullptr)
     {
     }
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -4325,16 +4325,22 @@ nsPIDOMWindowInner::IsPlayingAudio()
   if (!outer) {
     // We've been unlinked and are about to die.  Not a good time to pretend to
     // be playing audio.
     return false;
   }
   return acs->IsWindowActive(outer);
 }
 
+bool
+nsPIDOMWindowInner::IsDocumentLoaded() const
+{
+  return mIsDocumentLoaded;
+}
+
 mozilla::dom::TimeoutManager&
 nsPIDOMWindowInner::TimeoutManager()
 {
   return *mTimeoutManager;
 }
 
 bool
 nsPIDOMWindowInner::IsRunningTimeout()
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -885,16 +885,18 @@ public:
   void Thaw();
 
   // Apply the parent window's suspend, freeze, and modal state to the current
   // window.
   void SyncStateFromParentWindow();
 
   bool IsPlayingAudio();
 
+  bool IsDocumentLoaded() const;
+
   mozilla::dom::TimeoutManager& TimeoutManager();
 
   bool IsRunningTimeout();
 
 protected:
   void CreatePerformanceObjectIfNeeded();
 };