gecko-dev/dom/base/TimeoutManager.h
Ehsan Akhgari 443e426d7c Bug 1321903 - Refactor the timeout/interval management code out of nsGlobalWindow; r=bkelly
This code now lives in TimeoutManager.  Note that this is a transition
state, the Timeout list management code also needs to be refactored out
later.

In order to simplify the lifetime management of the new class, its
lifetime is equal to the lifetime of its containing nsGlobalWindow.  In
a few places where we need to dispatch runnables to do asynchronous work
on this object, we hold the containing window alive to guarantee safety.

This patch also removes a bit of dead code that was left over from the
code removed in bug 1281793. See:
https://hg.mozilla.org/mozilla-central/rev/0ac748f4d677#l1.63
2016-12-13 14:08:47 -05:00

129 lines
4.6 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TimeoutManager_h__
#define mozilla_dom_TimeoutManager_h__
#include "mozilla/dom/Timeout.h"
class nsITimeoutHandler;
class nsGlobalWindow;
namespace mozilla {
namespace dom {
// This class manages the timeouts in a Window's setTimeout/setInterval pool.
class TimeoutManager final
{
public:
explicit TimeoutManager(nsGlobalWindow& aWindow);
TimeoutManager(const TimeoutManager& rhs) = delete;
void operator=(const TimeoutManager& rhs) = delete;
bool IsRunningTimeout() const { return mTimeoutFiringDepth > 0; }
static uint32_t GetNestingLevel() { return sNestingLevel; }
static void SetNestingLevel(uint32_t aLevel) { sNestingLevel = aLevel; }
bool HasTimeouts() const { return !mTimeouts.isEmpty(); }
nsresult SetTimeout(nsITimeoutHandler* aHandler,
int32_t interval, bool aIsInterval,
mozilla::dom::Timeout::Reason aReason,
int32_t* aReturn);
void ClearTimeout(int32_t aTimerId,
mozilla::dom::Timeout::Reason aReason);
// The timeout implementation functions.
void RunTimeout(mozilla::dom::Timeout* aTimeout);
// Return true if |aTimeout| needs to be reinserted into the timeout list.
bool RescheduleTimeout(mozilla::dom::Timeout* aTimeout, const TimeStamp& now,
bool aRunningPendingTimeouts);
void ClearAllTimeouts();
// Insert aTimeout into the list, before all timeouts that would
// fire after it, but no earlier than mTimeoutInsertionPoint, if any.
void InsertTimeoutIntoList(mozilla::dom::Timeout* aTimeout);
uint32_t GetTimeoutId(mozilla::dom::Timeout::Reason aReason);
// Apply back pressure to the window if the TabGroup ThrottledEventQueue
// exists and has too many runnables waiting to run. For example, increase
// the minimum timer delay, etc.
void MaybeApplyBackPressure();
// Check the current ThrottledEventQueue depth and update the back pressure
// 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;
// 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();
// These four methods are intended to be called from the corresponding methods
// on nsGlobalWindow.
void Suspend();
void Resume();
void Freeze();
void Thaw();
// Initialize TimeoutManager before the first time it is accessed.
static void Initialize();
// Run some code for each Timeout in our list.
template <class Callable>
void ForEachTimeout(Callable c)
{
for (Timeout* timeout = mTimeouts.getFirst();
timeout;
timeout = timeout->getNext()) {
c(timeout);
}
}
private:
nsresult ResetTimersForThrottleReduction(int32_t aPreviousThrottleDelayMS);
private:
// Each nsGlobalWindow object has a TimeoutManager member. This reference
// points to that holder object.
nsGlobalWindow& mWindow;
// mTimeouts is generally sorted by mWhen, unless mTimeoutInsertionPoint is
// non-null. In that case, the dummy timeout pointed to by
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
// that come after it.
mozilla::LinkedList<mozilla::dom::Timeout> mTimeouts;
// If mTimeoutInsertionPoint is non-null, insertions should happen after it.
// This is a dummy timeout at the moment; if that ever changes, the logic in
// ResetTimersForThrottleReduction needs to change.
mozilla::dom::Timeout* mTimeoutInsertionPoint;
uint32_t mTimeoutIdCounter;
uint32_t mTimeoutFiringDepth;
mozilla::dom::Timeout* mRunningTimeout;
// The current idle request callback timeout handle
uint32_t mIdleCallbackTimeoutCounter;
int32_t mBackPressureDelayMS;
static uint32_t sNestingLevel;
};
}
}
#endif