Bug 1665252 - remove allowpaymentrequest attribute from HTMLIFrameElement r=dom-worke...
[gecko.git] / dom / base / TimeoutManager.h
blob04b4767a442d966c3c5a1830dfde88c7736cf053
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_TimeoutManager_h__
8 #define mozilla_dom_TimeoutManager_h__
10 #include "mozilla/dom/Timeout.h"
11 #include "nsTArray.h"
13 class nsIEventTarget;
14 class nsITimer;
15 class nsGlobalWindowInner;
17 namespace mozilla {
19 class PerformanceCounter;
21 namespace dom {
23 class TimeoutExecutor;
24 class TimeoutHandler;
26 // This class manages the timeouts in a Window's setTimeout/setInterval pool.
27 class TimeoutManager final {
28 private:
29 struct Timeouts;
31 public:
32 TimeoutManager(nsGlobalWindowInner& aWindow, uint32_t aMaxIdleDeferMS);
33 ~TimeoutManager();
34 TimeoutManager(const TimeoutManager& rhs) = delete;
35 void operator=(const TimeoutManager& rhs) = delete;
37 bool IsRunningTimeout() const;
39 static uint32_t GetNestingLevel() { return sNestingLevel; }
40 static void SetNestingLevel(uint32_t aLevel) { sNestingLevel = aLevel; }
42 bool HasTimeouts() const {
43 return !mTimeouts.IsEmpty() || !mIdleTimeouts.IsEmpty();
46 nsresult SetTimeout(TimeoutHandler* aHandler, int32_t interval,
47 bool aIsInterval, mozilla::dom::Timeout::Reason aReason,
48 int32_t* aReturn);
49 void ClearTimeout(int32_t aTimerId, mozilla::dom::Timeout::Reason aReason);
50 bool ClearTimeoutInternal(int32_t aTimerId,
51 mozilla::dom::Timeout::Reason aReason,
52 bool aIsIdle);
54 // The timeout implementation functions.
55 MOZ_CAN_RUN_SCRIPT
56 void RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadline,
57 bool aProcessIdle);
59 void ClearAllTimeouts();
60 uint32_t GetTimeoutId(mozilla::dom::Timeout::Reason aReason);
62 TimeDuration CalculateDelay(Timeout* aTimeout) const;
64 // aTimeout is the timeout that we're about to start running. This function
65 // returns the current timeout.
66 mozilla::dom::Timeout* BeginRunningTimeout(mozilla::dom::Timeout* aTimeout);
67 // aTimeout is the last running timeout.
68 void EndRunningTimeout(mozilla::dom::Timeout* aTimeout);
70 void UnmarkGrayTimers();
72 // These four methods are intended to be called from the corresponding methods
73 // on nsGlobalWindow.
74 void Suspend();
75 void Resume();
76 void Freeze();
77 void Thaw();
79 // This should be called by nsGlobalWindow when the window might have moved
80 // to the background or foreground.
81 void UpdateBackgroundState();
83 // The document finished loading
84 void OnDocumentLoaded();
85 void StartThrottlingTimeouts();
87 // Run some code for each Timeout in our list. Note that this function
88 // doesn't guarantee that Timeouts are iterated in any particular order.
89 template <class Callable>
90 void ForEachUnorderedTimeout(Callable c) {
91 mIdleTimeouts.ForEach(c);
92 mTimeouts.ForEach(c);
95 void BeginSyncOperation();
96 void EndSyncOperation();
98 nsIEventTarget* EventTarget();
100 bool BudgetThrottlingEnabled(bool aIsBackground) const;
102 static const uint32_t InvalidFiringId;
104 void SetLoading(bool value);
106 private:
107 void MaybeStartThrottleTimeout();
109 // Return true if |aTimeout| needs to be reinserted into the timeout list.
110 bool RescheduleTimeout(mozilla::dom::Timeout* aTimeout,
111 const TimeStamp& aLastCallbackTime,
112 const TimeStamp& aCurrentNow);
114 void MoveIdleToActive();
116 bool IsBackground() const;
118 bool IsActive() const;
120 uint32_t CreateFiringId();
122 void DestroyFiringId(uint32_t aFiringId);
124 bool IsValidFiringId(uint32_t aFiringId) const;
126 bool IsInvalidFiringId(uint32_t aFiringId) const;
128 TimeDuration MinSchedulingDelay() const;
130 nsresult MaybeSchedule(const TimeStamp& aWhen,
131 const TimeStamp& aNow = TimeStamp::Now());
133 void RecordExecution(Timeout* aRunningTimeout, Timeout* aTimeout);
135 void UpdateBudget(const TimeStamp& aNow,
136 const TimeDuration& aDuration = TimeDuration());
138 mozilla::PerformanceCounter* GetPerformanceCounter();
140 private:
141 struct Timeouts {
142 explicit Timeouts(const TimeoutManager& aManager)
143 : mManager(aManager), mTimeouts(new Timeout::TimeoutSet()) {}
145 // Insert aTimeout into the list, before all timeouts that would
146 // fire after it, but no earlier than the last Timeout with a
147 // valid FiringId.
148 enum class SortBy { TimeRemaining, TimeWhen };
149 void Insert(mozilla::dom::Timeout* aTimeout, SortBy aSortBy);
151 const Timeout* GetFirst() const { return mTimeoutList.getFirst(); }
152 Timeout* GetFirst() { return mTimeoutList.getFirst(); }
153 const Timeout* GetLast() const { return mTimeoutList.getLast(); }
154 Timeout* GetLast() { return mTimeoutList.getLast(); }
155 bool IsEmpty() const { return mTimeoutList.isEmpty(); }
156 void InsertFront(Timeout* aTimeout) {
157 aTimeout->SetTimeoutContainer(mTimeouts);
158 mTimeoutList.insertFront(aTimeout);
160 void InsertBack(Timeout* aTimeout) {
161 aTimeout->SetTimeoutContainer(mTimeouts);
162 mTimeoutList.insertBack(aTimeout);
164 void Clear() {
165 mTimeouts->Clear();
166 mTimeoutList.clear();
169 template <class Callable>
170 void ForEach(Callable c) {
171 for (Timeout* timeout = GetFirst(); timeout;
172 timeout = timeout->getNext()) {
173 c(timeout);
177 // Returns true when a callback aborts iteration.
178 template <class Callable>
179 bool ForEachAbortable(Callable c) {
180 for (Timeout* timeout = GetFirst(); timeout;
181 timeout = timeout->getNext()) {
182 if (c(timeout)) {
183 return true;
186 return false;
189 Timeout* GetTimeout(uint32_t aTimeoutId, Timeout::Reason aReason) {
190 Timeout::TimeoutIdAndReason key = {aTimeoutId, aReason};
191 return mTimeouts->Get(key);
194 private:
195 // The TimeoutManager that owns this Timeouts structure. This is
196 // mainly used to call state inspecting methods like IsValidFiringId().
197 const TimeoutManager& mManager;
199 typedef mozilla::LinkedList<RefPtr<Timeout>> TimeoutList;
201 // mTimeoutList is generally sorted by mWhen, but new values are always
202 // inserted after any Timeouts with a valid FiringId.
203 TimeoutList mTimeoutList;
205 // mTimeouts is a set of all the timeouts in the mTimeoutList.
206 // It let's one to have O(1) check whether a timeout id/reason is in the
207 // list.
208 RefPtr<Timeout::TimeoutSet> mTimeouts;
211 // Each nsGlobalWindowInner object has a TimeoutManager member. This
212 // reference points to that holder object.
213 nsGlobalWindowInner& mWindow;
214 // The executor is specific to the nsGlobalWindow/TimeoutManager, but it
215 // can live past the destruction of the window if its scheduled. Therefore
216 // it must be a separate ref-counted object.
217 RefPtr<TimeoutExecutor> mExecutor;
218 // For timeouts run off the idle queue
219 RefPtr<TimeoutExecutor> mIdleExecutor;
220 // The list of timeouts coming from non-tracking scripts.
221 Timeouts mTimeouts;
222 uint32_t mTimeoutIdCounter;
223 uint32_t mNextFiringId;
224 #ifdef DEBUG
225 int64_t mFiringIndex;
226 int64_t mLastFiringIndex;
227 #endif
228 AutoTArray<uint32_t, 2> mFiringIdStack;
229 mozilla::dom::Timeout* mRunningTimeout;
231 // Timeouts that would have fired but are being deferred until MainThread
232 // is idle (because we're loading)
233 Timeouts mIdleTimeouts;
235 // The current idle request callback timeout handle
236 uint32_t mIdleCallbackTimeoutCounter;
238 nsCOMPtr<nsITimer> mThrottleTimeoutsTimer;
239 mozilla::TimeStamp mLastBudgetUpdate;
240 mozilla::TimeDuration mExecutionBudget;
242 bool mThrottleTimeouts;
243 bool mThrottleTrackingTimeouts;
244 bool mBudgetThrottleTimeouts;
246 bool mIsLoading;
248 static uint32_t sNestingLevel;
251 } // namespace dom
252 } // namespace mozilla
254 #endif