Bug 1316871 - Throttle background setTimeouts. r=bkelly
authorAndreas Farre <farre@mozilla.com>
Fri, 11 Nov 2016 16:38:15 +0100
changeset 325478 6474932e4e65d2f808803218fe0f306e14c0ff82
parent 325477 a77180ae4e06fe05353d97beaa750ec65c3ce2d6
child 325479 9211bfa02ed5d2807fba8253cff6eb9383ce3f5d
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersbkelly
bugs1316871
milestone53.0a1
Bug 1316871 - Throttle background setTimeouts. r=bkelly MozReview-Commit-ID: 2bN3NZfdCzv
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -314,18 +314,17 @@ int32_t gTimeoutCnt                     
 static int32_t gMinTimeoutValue;
 static int32_t gMinBackgroundTimeoutValue;
 inline int32_t
 nsGlobalWindow::DOMMinTimeoutValue() 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 baackground audio can keep running smoothly. (bug 1181073)
-  bool isBackground = mAudioContexts.IsEmpty() &&
-    (!mOuterWindow || mOuterWindow->IsBackground());
+  bool isBackground = mAudioContexts.IsEmpty() && IsBackgroundInternal();
   return
     std::max(isBackground ? gMinBackgroundTimeoutValue : gMinTimeoutValue, value);
 }
 
 // The number of nested timeouts before we start clamping. HTML5 says 1, WebKit
 // uses 5.
 #define DOM_CLAMP_TIMEOUT_NESTING_LEVEL 5
 
@@ -649,16 +648,21 @@ void nsGlobalWindow::UnthrottleIdleCallb
 
   while (!mThrottledIdleRequestCallbacks.isEmpty()) {
     RefPtr<IdleRequest> request(mThrottledIdleRequestCallbacks.popFirst());
     mIdleRequestCallbacks.insertBack(request);
     NS_IdleDispatchToCurrentThread(request.forget());
   }
 }
 
+bool
+nsGlobalWindow::IsBackgroundInternal() const
+{
+  return !mOuterWindow || mOuterWindow->IsBackground();
+}
 
 namespace mozilla {
 namespace dom {
 extern uint64_t
 NextWindowID();
 } // namespace dom
 } // namespace mozilla
 
@@ -12736,17 +12740,17 @@ nsGlobalWindow::SetTimeoutOrInterval(nsI
   timeout->mInterval = interval;
   timeout->mScriptHandler = aHandler;
   timeout->mReason = aReason;
 
   // 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) {
+      mBackPressureDelayMS > 0 || IsBackgroundInternal()) {
     // Don't allow timeouts less than DOMMinTimeoutValue() from
     // now...
     realInterval = std::max(realInterval, uint32_t(DOMMinTimeoutValue()));
   }
 
   TimeDuration delta = TimeDuration::FromMilliseconds(realInterval);
 
   if (IsFrozen()) {
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -1719,16 +1719,18 @@ private:
   // 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 aPreviousThrottleDelayMS);
 
   mozilla::dom::TabGroup* TabGroupInner();
   mozilla::dom::TabGroup* TabGroupOuter();
 
+  bool IsBackgroundInternal() const;
+
 public:
   // Dispatch a runnable related to the global.
   virtual nsresult Dispatch(const char* aName,
                             mozilla::dom::TaskCategory aCategory,
                             already_AddRefed<nsIRunnable>&& aRunnable) override;
 
   virtual already_AddRefed<nsIEventTarget>
   EventTargetFor(mozilla::dom::TaskCategory aCategory) const override;