Bug 1325467 - Part 2: Let TimeoutManager::DOMMinTimeoutValue know whethe the timeout being scheduled is tracking; r=bkelly
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 21 Dec 2016 22:40:10 -0500
changeset 374757 ae1b2492b2fce313ad59d594d4e3cc3d41aad879
parent 374756 00c84bfb500599f5a427a51f52145d0cde8cb204
child 374758 eca0ecd94ddc35b77f6c9b520f3196464abb727d
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly
bugs1325467
milestone53.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 1325467 - Part 2: Let TimeoutManager::DOMMinTimeoutValue know whethe the timeout being scheduled is tracking; r=bkelly
dom/base/TimeoutManager.cpp
dom/base/TimeoutManager.h
--- a/dom/base/TimeoutManager.cpp
+++ b/dom/base/TimeoutManager.cpp
@@ -18,17 +18,17 @@ using namespace mozilla::dom;
 static int32_t              gRunningTimeoutDepth       = 0;
 
 // The default shortest interval/timeout we permit
 #define DEFAULT_MIN_TIMEOUT_VALUE 4 // 4ms
 #define DEFAULT_MIN_BACKGROUND_TIMEOUT_VALUE 1000 // 1000ms
 static int32_t gMinTimeoutValue;
 static int32_t gMinBackgroundTimeoutValue;
 int32_t
-TimeoutManager::DOMMinTimeoutValue() const {
+TimeoutManager::DOMMinTimeoutValue(bool aIsTracking) const {
   // First apply any back pressure delay that might be in effect.
   int32_t value = std::max(mBackPressureDelayMS, 0);
   // Don't use the background timeout value when there are audio contexts
   // present, so that background audio can keep running smoothly. (bug 1181073)
   bool isBackground = !mWindow.AsInner()->HasAudioContexts() &&
     mWindow.IsBackgroundInternal();
   return
     std::max(isBackground ? gMinBackgroundTimeoutValue : gMinTimeoutValue, value);
@@ -190,17 +190,18 @@ TimeoutManager::SetTimeout(nsITimeoutHan
 
   // Now clamp the actual interval we will use for the timer based on
   uint32_t nestingLevel = sNestingLevel + 1;
   uint32_t realInterval = interval;
   if (aIsInterval || nestingLevel >= DOM_CLAMP_TIMEOUT_NESTING_LEVEL ||
       mBackPressureDelayMS > 0 || mWindow.IsBackgroundInternal()) {
     // Don't allow timeouts less than DOMMinTimeoutValue() from
     // now...
-    realInterval = std::max(realInterval, uint32_t(DOMMinTimeoutValue()));
+    realInterval = std::max(realInterval,
+                            uint32_t(DOMMinTimeoutValue(timeout->mIsTracking)));
   }
 
   timeout->mWindow = &mWindow;
 
   TimeDuration delta = TimeDuration::FromMilliseconds(realInterval);
   timeout->SetWhenOrTimeRemaining(TimeStamp::Now(), delta);
 
   // If we're not suspended, then set the timer.
@@ -675,18 +676,19 @@ TimeoutManager::RescheduleTimeout(Timeou
       aTimeout->Release();
     }
     return false;
   }
 
   // Compute time to next timeout for interval timer.
   // Make sure nextInterval is at least DOMMinTimeoutValue().
   TimeDuration nextInterval =
-    TimeDuration::FromMilliseconds(std::max(aTimeout->mInterval,
-                                          uint32_t(DOMMinTimeoutValue())));
+    TimeDuration::FromMilliseconds(
+        std::max(aTimeout->mInterval,
+                 uint32_t(DOMMinTimeoutValue(aTimeout->mIsTracking))));
 
   // If we're running pending timeouts, set the next interval to be
   // relative to "now", and not to when the timeout that was pending
   // should have fired.
   TimeStamp firingTime;
   if (aRunningPendingTimeouts) {
     firingTime = now + nextInterval;
   } else {
@@ -747,38 +749,37 @@ nsresult
 TimeoutManager::ResetTimersForThrottleReduction(int32_t aPreviousThrottleDelayMS)
 {
   MOZ_ASSERT(aPreviousThrottleDelayMS > 0);
 
   if (mWindow.IsFrozen() || mWindow.IsSuspended()) {
     return NS_OK;
   }
 
-  auto minTimeout = DOMMinTimeoutValue();
   Timeouts::SortBy sortBy = mWindow.IsFrozen() ? Timeouts::SortBy::TimeRemaining
                                                : Timeouts::SortBy::TimeWhen;
 
   nsCOMPtr<nsIEventTarget> queue = mWindow.EventTargetFor(TaskCategory::Timer);
   nsresult rv = mNormalTimeouts.ResetTimersForThrottleReduction(aPreviousThrottleDelayMS,
-                                                                minTimeout,
+                                                                *this,
                                                                 sortBy,
                                                                 queue);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = mTrackingTimeouts.ResetTimersForThrottleReduction(aPreviousThrottleDelayMS,
-                                                         minTimeout,
+                                                         *this,
                                                          sortBy,
                                                          queue);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 nsresult
 TimeoutManager::Timeouts::ResetTimersForThrottleReduction(int32_t aPreviousThrottleDelayMS,
-                                                          int32_t aMinTimeoutValueMS,
+                                                          const TimeoutManager& aTimeoutManager,
                                                           SortBy aSortBy,
                                                           nsIEventTarget* aQueue)
 {
   TimeStamp now = TimeStamp::Now();
 
   // If insertion point is non-null, we're in the middle of firing timers and
   // the timers we're planning to fire all come before insertion point;
   // insertion point itself is a dummy timeout with an When() that may be
@@ -804,18 +805,20 @@ TimeoutManager::Timeouts::ResetTimersFor
       // gMinBackgroundTimeoutValue ms and hence were not clamped.
       break;
     }
 
     // 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(aMinTimeoutValueMS)));
+      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);
     if (oldInterval > interval) {
       // unclamp
       TimeStamp firingTime =
         std::max(timeout->When() - oldInterval + interval, now);
 
@@ -1009,17 +1012,17 @@ TimeoutManager::Resume()
     // the deadline has already passed or falls within our minimum delay
     // deadline, then clamp the resulting value to the minimum delay.  The
     // When() will remain at its absolute time, but we won'aTimeout fire the OS
     // timer until our calculated delay has passed.
     int32_t remaining = 0;
     if (aTimeout->When() > now) {
       remaining = static_cast<int32_t>((aTimeout->When() - now).ToMilliseconds());
     }
-    uint32_t delay = std::max(remaining, DOMMinTimeoutValue());
+    uint32_t delay = std::max(remaining, DOMMinTimeoutValue(aTimeout->mIsTracking));
 
     aTimeout->mTimer = do_CreateInstance("@mozilla.org/timer;1");
     if (!aTimeout->mTimer) {
       aTimeout->remove();
       return;
     }
 
     nsresult rv = aTimeout->InitTimer(mWindow.EventTargetFor(TaskCategory::Timer),
--- a/dom/base/TimeoutManager.h
+++ b/dom/base/TimeoutManager.h
@@ -62,17 +62,17 @@ public:
   // state.  If the queue has drained back pressure may be canceled.
   void CancelOrUpdateBackPressure(nsGlobalWindow* aWindow);
 
   // When timers are being throttled and we reduce the thottle delay we must
   // reschedule.  The amount of the old throttle delay must be provided in
   // order to bound how many timers must be examined.
   nsresult ResetTimersForThrottleReduction();
 
-  int32_t DOMMinTimeoutValue() const;
+  int32_t DOMMinTimeoutValue(bool aIsTracking) const;
 
   // aTimeout is the timeout that we're about to start running.  This function
   // returns the current timeout.
   mozilla::dom::Timeout* BeginRunningTimeout(mozilla::dom::Timeout* aTimeout);
   // aTimeout is the last running timeout.
   void EndRunningTimeout(mozilla::dom::Timeout* aTimeout);
 
   void UnmarkGrayTimers();
@@ -124,17 +124,17 @@ private:
     // fire after it, but no earlier than mTimeoutInsertionPoint, if any.
     enum class SortBy
     {
       TimeRemaining,
       TimeWhen
     };
     void Insert(mozilla::dom::Timeout* aTimeout, SortBy aSortBy);
     nsresult ResetTimersForThrottleReduction(int32_t aPreviousThrottleDelayMS,
-                                             int32_t aMinTimeoutValueMS,
+                                             const TimeoutManager& aTimeoutManager,
                                              SortBy aSortBy,
                                              nsIEventTarget* aQueue);
 
     const Timeout* GetFirst() const { return mTimeoutList.getFirst(); }
     Timeout* GetFirst() { return mTimeoutList.getFirst(); }
     const Timeout* GetLast() const { return mTimeoutList.getLast(); }
     Timeout* GetLast() { return mTimeoutList.getLast(); }
     bool IsEmpty() const { return mTimeoutList.isEmpty(); }