Bug 1363829 P4 Store the scheduled delay on Timeout instead of relying on the nsITimer to hold it. r=ehsan
authorBen Kelly <ben@wanderview.com>
Wed, 31 May 2017 17:13:18 -0700
changeset 409857 aea41a0174ae49453fe22b261e58c000655460a9
parent 409856 60ce370ec87bc95dfbfcace418a8fadbfe8fff7e
child 409858 9ac282f673708b4ec618b135829da348529778f4
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)
reviewersehsan
bugs1363829
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 1363829 P4 Store the scheduled delay on Timeout instead of relying on the nsITimer to hold it. r=ehsan
dom/base/Timeout.cpp
dom/base/Timeout.h
dom/base/TimeoutManager.cpp
--- a/dom/base/Timeout.cpp
+++ b/dom/base/Timeout.cpp
@@ -137,24 +137,26 @@ Timeout::SetWhenOrTimeRemaining(const Ti
 
   // If we are frozen simply set mTimeRemaining to be the "time remaining" in
   // the timeout (i.e., the interval itself).  This will be used to create a
   // new mWhen time when the window is thawed.  The end effect is that time does
   // not appear to pass for frozen windows.
   if (mWindow->IsFrozen()) {
     mWhen = TimeStamp();
     mTimeRemaining = aDelay;
+    mScheduledDelay = TimeDuration(0);
     return;
   }
 
   // Since we are not frozen we must set a precise mWhen target wakeup
   // time.  Even if we are suspended we want to use this target time so
   // that it appears time passes while suspended.
   mWhen = aBaseTime + aDelay;
   mTimeRemaining = TimeDuration(0);
+  mScheduledDelay = aDelay;
 }
 
 void
 Timeout::SetDummyWhen(const TimeStamp& aWhen)
 {
   MOZ_DIAGNOSTIC_ASSERT(!mWindow);
   mWhen = aWhen;
 }
@@ -172,10 +174,17 @@ const TimeDuration&
 Timeout::TimeRemaining() const
 {
   MOZ_DIAGNOSTIC_ASSERT(mWhen.IsNull());
   // Note, mWindow->IsFrozen() can be false here.  The Thaw() method calls
   // TimeRemaining() to calculate the new When() value.
   return mTimeRemaining;
 }
 
+const TimeDuration&
+Timeout::ScheduledDelay() const
+{
+  MOZ_DIAGNOSTIC_ASSERT(!mWhen.IsNull());
+  return mScheduledDelay;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/Timeout.h
+++ b/dom/base/Timeout.h
@@ -55,16 +55,19 @@ public:
   void SetDummyWhen(const TimeStamp& aWhen);
 
   // Can only be called when not frozen.
   const TimeStamp& When() const;
 
   // Can only be called when frozen.
   const TimeDuration& TimeRemaining() const;
 
+  // Can only be called when not frozen.
+  const TimeDuration& ScheduledDelay() const;
+
   // Window for which this timeout fires
   RefPtr<nsGlobalWindow> mWindow;
 
   // The actual timer object
   nsCOMPtr<nsITimer> mTimer;
 
   // True if the timeout was cleared
   bool mCleared;
@@ -104,18 +107,23 @@ public:
   RefPtr<Timeout> mClosureSelfRef;
 
 private:
   // mWhen and mTimeRemaining can't be in a union, sadly, because they
   // have constructors.
   // Nominal time to run this timeout.  Use only when timeouts are not
   // frozen.
   TimeStamp mWhen;
+
   // Remaining time to wait.  Used only when timeouts are frozen.
   TimeDuration mTimeRemaining;
 
+  // The actual interval in milliseconds.  This may be throttled to
+  // a longer delay than mInterval for a number of reasons.
+  TimeDuration mScheduledDelay;
+
   ~Timeout();
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_timeout_h
--- a/dom/base/TimeoutManager.cpp
+++ b/dom/base/TimeoutManager.cpp
@@ -1085,19 +1085,17 @@ TimeoutManager::Timeouts::ResetTimersFor
     // We reduced our throttled delay. Re-init the timer appropriately.
     // Compute the interval the timer should have had if it had not been set in a
     // background window
     TimeDuration interval =
       TimeDuration::FromMilliseconds(
           std::max(timeout->mInterval,
                    uint32_t(aTimeoutManager.
                                 DOMMinTimeoutValue(timeout->mIsTracking))));
-    uint32_t oldIntervalMillisecs = 0;
-    timeout->mTimer->GetDelay(&oldIntervalMillisecs);
-    TimeDuration oldInterval = TimeDuration::FromMilliseconds(oldIntervalMillisecs);
+    const TimeDuration& oldInterval = timeout->ScheduledDelay();
     if (oldInterval > interval) {
       // unclamp
       TimeStamp firingTime =
         std::max(timeout->When() - oldInterval + interval, now);
 
       NS_ASSERTION(firingTime < timeout->When(),
                    "Our firing time should strictly decrease!");