1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/* -*- 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_timeoutexecutor_h
#define mozilla_dom_timeoutexecutor_h
#include "mozilla/TimeStamp.h"
#include "nsCOMPtr.h"
#include "nsIRunnable.h"
#include "nsITimer.h"
#include "nsINamed.h"
namespace mozilla::dom {
class TimeoutManager;
class TimeoutExecutor final : public nsIRunnable,
public nsITimerCallback,
public nsINamed {
TimeoutManager* mOwner;
bool mIsIdleQueue;
nsCOMPtr<nsITimer> mTimer;
TimeStamp mDeadline;
uint32_t mMaxIdleDeferMS;
// Limits how far we allow timers to fire into the future from their
// deadline. Starts off at zero, but is then adjusted when we start
// using nsITimer. The nsITimer implementation may sometimes fire
// early and we should allow that to minimize additional wakeups.
TimeDuration mAllowedEarlyFiringTime;
// The TimeoutExecutor is repeatedly scheduled by the TimeoutManager
// to fire for the next soonest Timeout. Since the executor is re-used
// it needs to handle switching between a few states.
enum class Mode {
// None indicates the executor is idle. It may be scheduled or shutdown.
None,
// Immediate means the executor is scheduled to run a Timeout with a
// deadline that has already expired.
Immediate,
// Delayed means the executor is scheduled to run a Timeout with a
// deadline in the future.
Delayed,
// Shutdown means the TimeoutManager has been destroyed. Once this
// state is reached the executor cannot be scheduled again. If the
// executor is already dispatched as a runnable or held by a timer then
// we may still get a Run()/Notify() call which will be ignored.
Shutdown
};
Mode mMode;
~TimeoutExecutor();
nsresult ScheduleImmediate(const TimeStamp& aDeadline, const TimeStamp& aNow);
nsresult ScheduleDelayed(const TimeStamp& aDeadline, const TimeStamp& aNow,
const TimeDuration& aMinDelay);
nsresult Schedule(const TimeStamp& aDeadline, const TimeDuration& aMinDelay);
nsresult MaybeReschedule(const TimeStamp& aDeadline,
const TimeDuration& aMinDelay);
MOZ_CAN_RUN_SCRIPT void MaybeExecute();
public:
TimeoutExecutor(TimeoutManager* aOwner, bool aIsIdleQueue,
uint32_t aMaxIdleDeferMS);
void Shutdown();
nsresult MaybeSchedule(const TimeStamp& aDeadline,
const TimeDuration& aMinDelay);
void Cancel();
NS_DECL_ISUPPORTS
NS_DECL_NSIRUNNABLE
NS_DECL_NSITIMERCALLBACK
NS_DECL_NSINAMED
};
} // namespace mozilla::dom
#endif // mozilla_dom_timeoutexecutor_h
|