Bug 1316871 - Throttle background setTimeouts. r=bkelly
MozReview-Commit-ID: 2bN3NZfdCzv
--- 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;