Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/base/TimeoutManager.h
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#ifndef mozilla_dom_TimeoutManager_h__
8
#define mozilla_dom_TimeoutManager_h__
9
10
#include "mozilla/dom/Timeout.h"
11
#include "nsTArray.h"
12
13
class nsIEventTarget;
14
class nsITimeoutHandler;
15
class nsITimer;
16
class nsGlobalWindowInner;
17
18
namespace mozilla {
19
20
class PerformanceCounter;
21
22
namespace dom {
23
24
class OrderedTimeoutIterator;
25
class TimeoutExecutor;
26
27
// This class manages the timeouts in a Window's setTimeout/setInterval pool.
28
class TimeoutManager final
29
{
30
public:
31
  explicit TimeoutManager(nsGlobalWindowInner& aWindow);
32
  ~TimeoutManager();
33
  TimeoutManager(const TimeoutManager& rhs) = delete;
34
  void operator=(const TimeoutManager& rhs) = delete;
35
36
  bool IsRunningTimeout() const;
37
38
  static uint32_t GetNestingLevel() { return sNestingLevel; }
39
  static void SetNestingLevel(uint32_t aLevel) { sNestingLevel = aLevel; }
40
41
  bool HasTimeouts() const
42
0
  {
43
0
    return !mNormalTimeouts.IsEmpty() ||
44
0
           !mTrackingTimeouts.IsEmpty();
45
0
  }
46
47
  nsresult SetTimeout(nsITimeoutHandler* aHandler,
48
                      int32_t interval, bool aIsInterval,
49
                      mozilla::dom::Timeout::Reason aReason,
50
                      int32_t* aReturn);
51
  void ClearTimeout(int32_t aTimerId,
52
                    mozilla::dom::Timeout::Reason aReason);
53
54
  // The timeout implementation functions.
55
  void RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadline);
56
57
  void ClearAllTimeouts();
58
  uint32_t GetTimeoutId(mozilla::dom::Timeout::Reason aReason);
59
60
  TimeDuration CalculateDelay(Timeout* aTimeout) const;
61
62
  // aTimeout is the timeout that we're about to start running.  This function
63
  // returns the current timeout.
64
  mozilla::dom::Timeout* BeginRunningTimeout(mozilla::dom::Timeout* aTimeout);
65
  // aTimeout is the last running timeout.
66
  void EndRunningTimeout(mozilla::dom::Timeout* aTimeout);
67
68
  void UnmarkGrayTimers();
69
70
  // These four methods are intended to be called from the corresponding methods
71
  // on nsGlobalWindow.
72
  void Suspend();
73
  void Resume();
74
  void Freeze();
75
  void Thaw();
76
77
  // This should be called by nsGlobalWindow when the window might have moved
78
  // to the background or foreground.
79
  void UpdateBackgroundState();
80
81
  // Initialize TimeoutManager before the first time it is accessed.
82
  static void Initialize();
83
84
  // Exposed only for testing
85
  bool IsTimeoutTracking(uint32_t aTimeoutId);
86
87
  // The document finished loading
88
  void OnDocumentLoaded();
89
  void StartThrottlingTimeouts();
90
91
  // Run some code for each Timeout in our list.  Note that this function
92
  // doesn't guarantee that Timeouts are iterated in any particular order.
93
  template <class Callable>
94
  void ForEachUnorderedTimeout(Callable c)
95
0
  {
96
0
    mNormalTimeouts.ForEach(c);
97
0
    mTrackingTimeouts.ForEach(c);
98
0
  }
Unexecuted instantiation: Unified_cpp_dom_base5.cpp:void mozilla::dom::TimeoutManager::ForEachUnorderedTimeout<mozilla::dom::TimeoutManager::ClearAllTimeouts()::$_2>(mozilla::dom::TimeoutManager::ClearAllTimeouts()::$_2)
Unexecuted instantiation: Unified_cpp_dom_base5.cpp:void mozilla::dom::TimeoutManager::ForEachUnorderedTimeout<mozilla::dom::TimeoutManager::UnmarkGrayTimers()::$_3>(mozilla::dom::TimeoutManager::UnmarkGrayTimers()::$_3)
Unexecuted instantiation: Unified_cpp_dom_base5.cpp:void mozilla::dom::TimeoutManager::ForEachUnorderedTimeout<mozilla::dom::TimeoutManager::Freeze()::$_4>(mozilla::dom::TimeoutManager::Freeze()::$_4)
Unexecuted instantiation: Unified_cpp_dom_base5.cpp:void mozilla::dom::TimeoutManager::ForEachUnorderedTimeout<mozilla::dom::TimeoutManager::Thaw()::$_5>(mozilla::dom::TimeoutManager::Thaw()::$_5)
99
100
  // Run some code for each Timeout in our list, but let the callback cancel the
101
  // iteration by returning true.  Note that this function doesn't guarantee
102
  // that Timeouts are iterated in any particular order.
103
  template <class Callable>
104
  void ForEachUnorderedTimeoutAbortable(Callable c)
105
0
  {
106
0
    if (!mNormalTimeouts.ForEachAbortable(c)) {
107
0
      mTrackingTimeouts.ForEachAbortable(c);
108
0
    }
109
0
  }
110
111
  void BeginSyncOperation();
112
  void EndSyncOperation();
113
114
  nsIEventTarget*
115
  EventTarget();
116
117
  bool BudgetThrottlingEnabled(bool aIsBackground) const;
118
119
  static const uint32_t InvalidFiringId;
120
121
private:
122
  void MaybeStartThrottleTimeout();
123
124
  // Return true if |aTimeout| needs to be reinserted into the timeout list.
125
  bool RescheduleTimeout(mozilla::dom::Timeout* aTimeout,
126
                         const TimeStamp& aLastCallbackTime,
127
                         const TimeStamp& aCurrentNow);
128
129
  bool IsBackground() const;
130
131
  bool IsActive() const;
132
133
  uint32_t
134
  CreateFiringId();
135
136
  void
137
  DestroyFiringId(uint32_t aFiringId);
138
139
  bool
140
  IsValidFiringId(uint32_t aFiringId) const;
141
142
  bool
143
  IsInvalidFiringId(uint32_t aFiringId) const;
144
145
  TimeDuration
146
  MinSchedulingDelay() const;
147
148
  nsresult MaybeSchedule(const TimeStamp& aWhen,
149
                         const TimeStamp& aNow = TimeStamp::Now());
150
151
  void RecordExecution(Timeout* aRunningTimeout,
152
                       Timeout* aTimeout);
153
154
  void UpdateBudget(const TimeStamp& aNow,
155
                    const TimeDuration& aDuration = TimeDuration());
156
157
  mozilla::PerformanceCounter* GetPerformanceCounter();
158
private:
159
  struct Timeouts {
160
    explicit Timeouts(const TimeoutManager& aManager)
161
      : mManager(aManager)
162
0
    {
163
0
    }
164
165
    // Insert aTimeout into the list, before all timeouts that would
166
    // fire after it, but no earlier than the last Timeout with a
167
    // valid FiringId.
168
    enum class SortBy
169
    {
170
      TimeRemaining,
171
      TimeWhen
172
    };
173
    void Insert(mozilla::dom::Timeout* aTimeout, SortBy aSortBy);
174
175
    const Timeout* GetFirst() const { return mTimeoutList.getFirst(); }
176
    Timeout* GetFirst() { return mTimeoutList.getFirst(); }
177
    const Timeout* GetLast() const { return mTimeoutList.getLast(); }
178
0
    Timeout* GetLast() { return mTimeoutList.getLast(); }
179
0
    bool IsEmpty() const { return mTimeoutList.isEmpty(); }
180
0
    void InsertFront(Timeout* aTimeout) { mTimeoutList.insertFront(aTimeout); }
181
0
    void Clear() { mTimeoutList.clear(); }
182
183
    template <class Callable>
184
    void ForEach(Callable c)
185
0
    {
186
0
      for (Timeout* timeout = GetFirst();
187
0
           timeout;
188
0
           timeout = timeout->getNext()) {
189
0
        c(timeout);
190
0
      }
191
0
    }
Unexecuted instantiation: Unified_cpp_dom_base5.cpp:void mozilla::dom::TimeoutManager::Timeouts::ForEach<mozilla::dom::TimeoutManager::ClearAllTimeouts()::$_2>(mozilla::dom::TimeoutManager::ClearAllTimeouts()::$_2)
Unexecuted instantiation: Unified_cpp_dom_base5.cpp:void mozilla::dom::TimeoutManager::Timeouts::ForEach<mozilla::dom::TimeoutManager::UnmarkGrayTimers()::$_3>(mozilla::dom::TimeoutManager::UnmarkGrayTimers()::$_3)
Unexecuted instantiation: Unified_cpp_dom_base5.cpp:void mozilla::dom::TimeoutManager::Timeouts::ForEach<mozilla::dom::TimeoutManager::Freeze()::$_4>(mozilla::dom::TimeoutManager::Freeze()::$_4)
Unexecuted instantiation: Unified_cpp_dom_base5.cpp:void mozilla::dom::TimeoutManager::Timeouts::ForEach<mozilla::dom::TimeoutManager::Thaw()::$_5>(mozilla::dom::TimeoutManager::Thaw()::$_5)
192
193
    // Returns true when a callback aborts iteration.
194
    template <class Callable>
195
    bool ForEachAbortable(Callable c)
196
0
    {
197
0
      for (Timeout* timeout = GetFirst();
198
0
           timeout;
199
0
           timeout = timeout->getNext()) {
200
0
        if (c(timeout)) {
201
0
          return true;
202
0
        }
203
0
      }
204
0
      return false;
205
0
    }
Unexecuted instantiation: Unified_cpp_dom_base5.cpp:bool mozilla::dom::TimeoutManager::Timeouts::ForEachAbortable<mozilla::dom::TimeoutManager::ClearTimeout(int, mozilla::dom::Timeout::Reason)::$_0>(mozilla::dom::TimeoutManager::ClearTimeout(int, mozilla::dom::Timeout::Reason)::$_0)
Unexecuted instantiation: Unified_cpp_dom_base5.cpp:bool mozilla::dom::TimeoutManager::Timeouts::ForEachAbortable<mozilla::dom::TimeoutManager::IsTimeoutTracking(unsigned int)::$_6>(mozilla::dom::TimeoutManager::IsTimeoutTracking(unsigned int)::$_6)
206
207
    friend class OrderedTimeoutIterator;
208
209
  private:
210
    // The TimeoutManager that owns this Timeouts structure.  This is
211
    // mainly used to call state inspecting methods like IsValidFiringId().
212
    const TimeoutManager&     mManager;
213
214
    typedef mozilla::LinkedList<RefPtr<Timeout>> TimeoutList;
215
216
    // mTimeoutList is generally sorted by mWhen, but new values are always
217
    // inserted after any Timeouts with a valid FiringId.
218
    TimeoutList               mTimeoutList;
219
  };
220
221
  friend class OrderedTimeoutIterator;
222
223
  // Each nsGlobalWindowInner object has a TimeoutManager member.  This reference
224
  // points to that holder object.
225
  nsGlobalWindowInner&             mWindow;
226
  // The executor is specific to the nsGlobalWindow/TimeoutManager, but it
227
  // can live past the destruction of the window if its scheduled.  Therefore
228
  // it must be a separate ref-counted object.
229
  RefPtr<TimeoutExecutor>     mExecutor;
230
  // The list of timeouts coming from non-tracking scripts.
231
  Timeouts                    mNormalTimeouts;
232
  // The list of timeouts coming from scripts on the tracking protection list.
233
  Timeouts                    mTrackingTimeouts;
234
  uint32_t                    mTimeoutIdCounter;
235
  uint32_t                    mNextFiringId;
236
  AutoTArray<uint32_t, 2>     mFiringIdStack;
237
  mozilla::dom::Timeout*      mRunningTimeout;
238
239
   // The current idle request callback timeout handle
240
  uint32_t                    mIdleCallbackTimeoutCounter;
241
242
  nsCOMPtr<nsITimer>          mThrottleTimeoutsTimer;
243
  mozilla::TimeStamp          mLastBudgetUpdate;
244
  mozilla::TimeDuration       mExecutionBudget;
245
246
  bool                        mThrottleTimeouts;
247
  bool                        mThrottleTrackingTimeouts;
248
  bool                        mBudgetThrottleTimeouts;
249
250
  static uint32_t             sNestingLevel;
251
};
252
253
}
254
}
255
256
#endif