xref: /aosp_15_r20/external/cronet/base/timer/timer.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker // A "timer" takes care of invoking a callback in the future, once or
6*6777b538SAndroid Build Coastguard Worker // repeatedly. The callback is invoked:
7*6777b538SAndroid Build Coastguard Worker // - OneShotTimer: Once after a `TimeDelta` delay has elapsed.
8*6777b538SAndroid Build Coastguard Worker // - RetainingOneShotTimer: Same as OneShotTimer, but the callback is retained
9*6777b538SAndroid Build Coastguard Worker //    after being executed, allowing another invocation to be scheduled with
10*6777b538SAndroid Build Coastguard Worker //    Reset() without specifying the callback again.
11*6777b538SAndroid Build Coastguard Worker // - DeadlineTimer: Once at the specified `TimeTicks` time.
12*6777b538SAndroid Build Coastguard Worker // - RepeatingTimer: Repeatedly, with a specified `TimeDelta` delay before the
13*6777b538SAndroid Build Coastguard Worker //    first invocation and between invocations.
14*6777b538SAndroid Build Coastguard Worker // - MetronomeTimer: Repeatedly, with a specified `TimeDelta` delay between the
15*6777b538SAndroid Build Coastguard Worker //    beginning of each invocations such that a constant phase is respected.
16*6777b538SAndroid Build Coastguard Worker // (Retaining)OneShotTimer and RepeatingTimer automatically apply some leeway to
17*6777b538SAndroid Build Coastguard Worker // the delay whereas DeadlineTimer and MetronomeTimer allow more control over
18*6777b538SAndroid Build Coastguard Worker // the requested time. As a result, the former are generally more
19*6777b538SAndroid Build Coastguard Worker // power-efficient.
20*6777b538SAndroid Build Coastguard Worker // Prefer using (Retaining)OneShotTimer and RepeatingTimer because they
21*6777b538SAndroid Build Coastguard Worker // automatically apply some leeway to the delay which enables power-efficient
22*6777b538SAndroid Build Coastguard Worker // scheduling.
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker // Scheduled invocations can be cancelled with Stop() or by deleting the
25*6777b538SAndroid Build Coastguard Worker // Timer. The latter makes it easy to ensure that an object is not accessed by a
26*6777b538SAndroid Build Coastguard Worker // Timer after it has been deleted: just make the Timer a member of the object
27*6777b538SAndroid Build Coastguard Worker // which receives Timer events (see example below).
28*6777b538SAndroid Build Coastguard Worker //
29*6777b538SAndroid Build Coastguard Worker // Sample RepeatingTimer usage:
30*6777b538SAndroid Build Coastguard Worker //
31*6777b538SAndroid Build Coastguard Worker //   class MyClass {
32*6777b538SAndroid Build Coastguard Worker //    public:
33*6777b538SAndroid Build Coastguard Worker //     void StartDoingStuff() {
34*6777b538SAndroid Build Coastguard Worker //       timer_.Start(FROM_HERE, base::Seconds(1),
35*6777b538SAndroid Build Coastguard Worker //                    this, &MyClass::DoStuff);
36*6777b538SAndroid Build Coastguard Worker //       // Alternative form if the callback is not bound to `this` or
37*6777b538SAndroid Build Coastguard Worker //       // requires arguments:
38*6777b538SAndroid Build Coastguard Worker //       //    timer_.Start(FROM_HERE, base::Seconds(1),
39*6777b538SAndroid Build Coastguard Worker //       //                 base::BindRepeating(&MyFunction, 42));
40*6777b538SAndroid Build Coastguard Worker //     }
41*6777b538SAndroid Build Coastguard Worker //     void StopDoingStuff() {
42*6777b538SAndroid Build Coastguard Worker //       timer_.Stop();
43*6777b538SAndroid Build Coastguard Worker //     }
44*6777b538SAndroid Build Coastguard Worker //    private:
45*6777b538SAndroid Build Coastguard Worker //     void DoStuff() {
46*6777b538SAndroid Build Coastguard Worker //       // This method is called every second to do stuff.
47*6777b538SAndroid Build Coastguard Worker //       ...
48*6777b538SAndroid Build Coastguard Worker //     }
49*6777b538SAndroid Build Coastguard Worker //     base::RepeatingTimer timer_;
50*6777b538SAndroid Build Coastguard Worker //   };
51*6777b538SAndroid Build Coastguard Worker //
52*6777b538SAndroid Build Coastguard Worker // These APIs are not thread safe. When a method is called (except the
53*6777b538SAndroid Build Coastguard Worker // constructor), all further method calls must be on the same sequence until
54*6777b538SAndroid Build Coastguard Worker // Stop(). Once stopped, it may be destroyed or restarted on another sequence.
55*6777b538SAndroid Build Coastguard Worker //
56*6777b538SAndroid Build Coastguard Worker // By default, the scheduled tasks will be run on the same sequence that the
57*6777b538SAndroid Build Coastguard Worker // Timer was *started on*. To mock time in unit tests, some old tests used
58*6777b538SAndroid Build Coastguard Worker // SetTaskRunner() to schedule the delay on a test-controlled TaskRunner. The
59*6777b538SAndroid Build Coastguard Worker // modern and preferred approach to mock time is to use TaskEnvironment's
60*6777b538SAndroid Build Coastguard Worker // MOCK_TIME mode.
61*6777b538SAndroid Build Coastguard Worker 
62*6777b538SAndroid Build Coastguard Worker #ifndef BASE_TIMER_TIMER_H_
63*6777b538SAndroid Build Coastguard Worker #define BASE_TIMER_TIMER_H_
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker // IMPORTANT: If you change timer code, make sure that all tests (including
66*6777b538SAndroid Build Coastguard Worker // disabled ones) from timer_unittests.cc pass locally. Some are disabled
67*6777b538SAndroid Build Coastguard Worker // because they're flaky on the buildbot, but when you run them locally you
68*6777b538SAndroid Build Coastguard Worker // should be able to tell the difference.
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
71*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
72*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
73*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
74*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
75*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
76*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker.h"
77*6777b538SAndroid Build Coastguard Worker #include "base/task/delayed_task_handle.h"
78*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner.h"
79*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
80*6777b538SAndroid Build Coastguard Worker #include "base/types/strong_alias.h"
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker namespace base {
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker class TickClock;
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker namespace internal {
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker // This class wraps logic shared by all timers.
89*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT TimerBase {
90*6777b538SAndroid Build Coastguard Worker  public:
91*6777b538SAndroid Build Coastguard Worker   TimerBase(const TimerBase&) = delete;
92*6777b538SAndroid Build Coastguard Worker   TimerBase& operator=(const TimerBase&) = delete;
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker   virtual ~TimerBase();
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker   // Returns true if the timer is running (i.e., not stopped).
97*6777b538SAndroid Build Coastguard Worker   bool IsRunning() const;
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker   // Sets the task runner on which the delayed task should be scheduled when
100*6777b538SAndroid Build Coastguard Worker   // this Timer is running. This method can only be called while this Timer
101*6777b538SAndroid Build Coastguard Worker   // isn't running. If this is used to mock time in tests, the modern and
102*6777b538SAndroid Build Coastguard Worker   // preferred approach is to use TaskEnvironment::TimeSource::MOCK_TIME. To
103*6777b538SAndroid Build Coastguard Worker   // avoid racy usage of Timer, |task_runner| must run tasks on the same
104*6777b538SAndroid Build Coastguard Worker   // sequence which this Timer is bound to (started from). TODO(gab): Migrate
105*6777b538SAndroid Build Coastguard Worker   // callers using this as a test seam to
106*6777b538SAndroid Build Coastguard Worker   // TaskEnvironment::TimeSource::MOCK_TIME.
107*6777b538SAndroid Build Coastguard Worker   virtual void SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner);
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker   // Call this method to stop the timer and cancel all previously scheduled
110*6777b538SAndroid Build Coastguard Worker   // tasks. It is a no-op if the timer is not running.
111*6777b538SAndroid Build Coastguard Worker   virtual void Stop();
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker  protected:
114*6777b538SAndroid Build Coastguard Worker   // Constructs a timer. Start must be called later to set task info.
115*6777b538SAndroid Build Coastguard Worker   explicit TimerBase(const Location& posted_from = Location());
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker   virtual void OnStop() = 0;
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   // Disables the scheduled task and abandons it so that it no longer refers
120*6777b538SAndroid Build Coastguard Worker   // back to this object.
121*6777b538SAndroid Build Coastguard Worker   void AbandonScheduledTask();
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   // Returns the task runner on which the task should be scheduled. If the
124*6777b538SAndroid Build Coastguard Worker   // corresponding |task_runner_| field is null, the task runner for the current
125*6777b538SAndroid Build Coastguard Worker   // sequence is returned.
126*6777b538SAndroid Build Coastguard Worker   scoped_refptr<SequencedTaskRunner> GetTaskRunner();
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker   // The task runner on which the task should be scheduled. If it is null, the
129*6777b538SAndroid Build Coastguard Worker   // task runner for the current sequence will be used.
130*6777b538SAndroid Build Coastguard Worker   scoped_refptr<SequencedTaskRunner> task_runner_;
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker   // Timer isn't thread-safe and while it is running, it must only be used on
133*6777b538SAndroid Build Coastguard Worker   // the same sequence until fully Stop()'ed. Once stopped, it may be destroyed
134*6777b538SAndroid Build Coastguard Worker   // or restarted on another sequence.
135*6777b538SAndroid Build Coastguard Worker   SEQUENCE_CHECKER(sequence_checker_);
136*6777b538SAndroid Build Coastguard Worker 
137*6777b538SAndroid Build Coastguard Worker   // Location in user code.
138*6777b538SAndroid Build Coastguard Worker   Location posted_from_ GUARDED_BY_CONTEXT(sequence_checker_);
139*6777b538SAndroid Build Coastguard Worker 
140*6777b538SAndroid Build Coastguard Worker   // The handle to the posted delayed task.
141*6777b538SAndroid Build Coastguard Worker   DelayedTaskHandle delayed_task_handle_ GUARDED_BY_CONTEXT(sequence_checker_);
142*6777b538SAndroid Build Coastguard Worker 
143*6777b538SAndroid Build Coastguard Worker   // Callback invoked when the timer is ready. This is saved as a member to
144*6777b538SAndroid Build Coastguard Worker   // avoid rebinding every time the Timer fires. Lazy initialized the first time
145*6777b538SAndroid Build Coastguard Worker   // the Timer is started.
146*6777b538SAndroid Build Coastguard Worker   RepeatingClosure timer_callback_;
147*6777b538SAndroid Build Coastguard Worker };
148*6777b538SAndroid Build Coastguard Worker 
149*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
150*6777b538SAndroid Build Coastguard Worker // This class wraps logic shared by (Retaining)OneShotTimer and RepeatingTimer.
151*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT DelayTimerBase : public TimerBase {
152*6777b538SAndroid Build Coastguard Worker  public:
153*6777b538SAndroid Build Coastguard Worker   DelayTimerBase(const DelayTimerBase&) = delete;
154*6777b538SAndroid Build Coastguard Worker   DelayTimerBase& operator=(const DelayTimerBase&) = delete;
155*6777b538SAndroid Build Coastguard Worker 
156*6777b538SAndroid Build Coastguard Worker   ~DelayTimerBase() override;
157*6777b538SAndroid Build Coastguard Worker 
158*6777b538SAndroid Build Coastguard Worker   // Returns the current delay for this timer.
159*6777b538SAndroid Build Coastguard Worker   TimeDelta GetCurrentDelay() const;
160*6777b538SAndroid Build Coastguard Worker 
161*6777b538SAndroid Build Coastguard Worker   // Call this method to reset the timer delay. The user task must be set. If
162*6777b538SAndroid Build Coastguard Worker   // the timer is not running, this will start it by posting a task.
163*6777b538SAndroid Build Coastguard Worker   virtual void Reset();
164*6777b538SAndroid Build Coastguard Worker 
165*6777b538SAndroid Build Coastguard Worker   // DEPRECATED. Call Stop() instead.
166*6777b538SAndroid Build Coastguard Worker   // TODO(1262205): Remove this method and all callers.
167*6777b538SAndroid Build Coastguard Worker   void AbandonAndStop();
168*6777b538SAndroid Build Coastguard Worker 
desired_run_time()169*6777b538SAndroid Build Coastguard Worker   TimeTicks desired_run_time() const {
170*6777b538SAndroid Build Coastguard Worker     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
171*6777b538SAndroid Build Coastguard Worker     return desired_run_time_;
172*6777b538SAndroid Build Coastguard Worker   }
173*6777b538SAndroid Build Coastguard Worker 
174*6777b538SAndroid Build Coastguard Worker  protected:
175*6777b538SAndroid Build Coastguard Worker   // Constructs a timer. Start must be called later to set task info.
176*6777b538SAndroid Build Coastguard Worker   // If |tick_clock| is provided, it is used instead of TimeTicks::Now() to get
177*6777b538SAndroid Build Coastguard Worker   // TimeTicks when scheduling tasks.
178*6777b538SAndroid Build Coastguard Worker   explicit DelayTimerBase(const TickClock* tick_clock = nullptr);
179*6777b538SAndroid Build Coastguard Worker 
180*6777b538SAndroid Build Coastguard Worker   // Construct a timer with task info.
181*6777b538SAndroid Build Coastguard Worker   // If |tick_clock| is provided, it is used instead of TimeTicks::Now() to get
182*6777b538SAndroid Build Coastguard Worker   // TimeTicks when scheduling tasks.
183*6777b538SAndroid Build Coastguard Worker   DelayTimerBase(const Location& posted_from,
184*6777b538SAndroid Build Coastguard Worker                  TimeDelta delay,
185*6777b538SAndroid Build Coastguard Worker                  const TickClock* tick_clock = nullptr);
186*6777b538SAndroid Build Coastguard Worker 
187*6777b538SAndroid Build Coastguard Worker   virtual void RunUserTask() = 0;
188*6777b538SAndroid Build Coastguard Worker 
189*6777b538SAndroid Build Coastguard Worker   // Schedules |OnScheduledTaskInvoked()| to run on the current sequence with
190*6777b538SAndroid Build Coastguard Worker   // the given |delay|. |desired_run_time_| is reset to Now() + delay.
191*6777b538SAndroid Build Coastguard Worker   void ScheduleNewTask(TimeDelta delay);
192*6777b538SAndroid Build Coastguard Worker 
193*6777b538SAndroid Build Coastguard Worker   void StartInternal(const Location& posted_from, TimeDelta delay);
194*6777b538SAndroid Build Coastguard Worker 
195*6777b538SAndroid Build Coastguard Worker  private:
196*6777b538SAndroid Build Coastguard Worker   // DCHECKs that the user task is not null. Used to diagnose a recurring bug
197*6777b538SAndroid Build Coastguard Worker   // where Reset() is called on a OneShotTimer that has already fired.
198*6777b538SAndroid Build Coastguard Worker   virtual void EnsureNonNullUserTask() = 0;
199*6777b538SAndroid Build Coastguard Worker 
200*6777b538SAndroid Build Coastguard Worker   // Returns the current tick count.
201*6777b538SAndroid Build Coastguard Worker   TimeTicks Now() const;
202*6777b538SAndroid Build Coastguard Worker 
203*6777b538SAndroid Build Coastguard Worker   // Called when the scheduled task is invoked. Will run the  |user_task| if the
204*6777b538SAndroid Build Coastguard Worker   // timer is still running and |desired_run_time_| was reached.
205*6777b538SAndroid Build Coastguard Worker   void OnScheduledTaskInvoked();
206*6777b538SAndroid Build Coastguard Worker 
207*6777b538SAndroid Build Coastguard Worker   // Delay requested by user.
208*6777b538SAndroid Build Coastguard Worker   TimeDelta delay_ GUARDED_BY_CONTEXT(sequence_checker_);
209*6777b538SAndroid Build Coastguard Worker 
210*6777b538SAndroid Build Coastguard Worker   // The desired run time of |user_task_|. The user may update this at any time,
211*6777b538SAndroid Build Coastguard Worker   // even if their previous request has not run yet. This time can be a "zero"
212*6777b538SAndroid Build Coastguard Worker   // TimeTicks if the task must be run immediately.
213*6777b538SAndroid Build Coastguard Worker   TimeTicks desired_run_time_ GUARDED_BY_CONTEXT(sequence_checker_);
214*6777b538SAndroid Build Coastguard Worker 
215*6777b538SAndroid Build Coastguard Worker   // The tick clock used to calculate the run time for scheduled tasks.
216*6777b538SAndroid Build Coastguard Worker   const raw_ptr<const TickClock> tick_clock_
217*6777b538SAndroid Build Coastguard Worker       GUARDED_BY_CONTEXT(sequence_checker_);
218*6777b538SAndroid Build Coastguard Worker };
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker }  // namespace internal
221*6777b538SAndroid Build Coastguard Worker 
222*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
223*6777b538SAndroid Build Coastguard Worker // A simple, one-shot timer.  See usage notes at the top of the file.
224*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT OneShotTimer : public internal::DelayTimerBase {
225*6777b538SAndroid Build Coastguard Worker  public:
226*6777b538SAndroid Build Coastguard Worker   OneShotTimer();
227*6777b538SAndroid Build Coastguard Worker   explicit OneShotTimer(const TickClock* tick_clock);
228*6777b538SAndroid Build Coastguard Worker 
229*6777b538SAndroid Build Coastguard Worker   OneShotTimer(const OneShotTimer&) = delete;
230*6777b538SAndroid Build Coastguard Worker   OneShotTimer& operator=(const OneShotTimer&) = delete;
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker   ~OneShotTimer() override;
233*6777b538SAndroid Build Coastguard Worker 
234*6777b538SAndroid Build Coastguard Worker   // Start the timer to run at the given |delay| from now. If the timer is
235*6777b538SAndroid Build Coastguard Worker   // already running, it will be replaced to call the given |user_task|.
236*6777b538SAndroid Build Coastguard Worker   virtual void Start(const Location& posted_from,
237*6777b538SAndroid Build Coastguard Worker                      TimeDelta delay,
238*6777b538SAndroid Build Coastguard Worker                      OnceClosure user_task);
239*6777b538SAndroid Build Coastguard Worker 
240*6777b538SAndroid Build Coastguard Worker   // Start the timer to run at the given |delay| from now. If the timer is
241*6777b538SAndroid Build Coastguard Worker   // already running, it will be replaced to call a task formed from
242*6777b538SAndroid Build Coastguard Worker   // |receiver->*method|.
243*6777b538SAndroid Build Coastguard Worker   template <class Receiver>
Start(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)())244*6777b538SAndroid Build Coastguard Worker   void Start(const Location& posted_from,
245*6777b538SAndroid Build Coastguard Worker              TimeDelta delay,
246*6777b538SAndroid Build Coastguard Worker              Receiver* receiver,
247*6777b538SAndroid Build Coastguard Worker              void (Receiver::*method)()) {
248*6777b538SAndroid Build Coastguard Worker     Start(posted_from, delay, BindOnce(method, Unretained(receiver)));
249*6777b538SAndroid Build Coastguard Worker   }
250*6777b538SAndroid Build Coastguard Worker 
251*6777b538SAndroid Build Coastguard Worker   // Run the scheduled task immediately, and stop the timer. The timer needs to
252*6777b538SAndroid Build Coastguard Worker   // be running.
253*6777b538SAndroid Build Coastguard Worker   virtual void FireNow();
254*6777b538SAndroid Build Coastguard Worker 
255*6777b538SAndroid Build Coastguard Worker  private:
256*6777b538SAndroid Build Coastguard Worker   void OnStop() final;
257*6777b538SAndroid Build Coastguard Worker   void RunUserTask() final;
258*6777b538SAndroid Build Coastguard Worker   void EnsureNonNullUserTask() final;
259*6777b538SAndroid Build Coastguard Worker 
260*6777b538SAndroid Build Coastguard Worker   OnceClosure user_task_;
261*6777b538SAndroid Build Coastguard Worker };
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
264*6777b538SAndroid Build Coastguard Worker // A simple, repeating timer.  See usage notes at the top of the file.
265*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT RepeatingTimer : public internal::DelayTimerBase {
266*6777b538SAndroid Build Coastguard Worker  public:
267*6777b538SAndroid Build Coastguard Worker   RepeatingTimer();
268*6777b538SAndroid Build Coastguard Worker   explicit RepeatingTimer(const TickClock* tick_clock);
269*6777b538SAndroid Build Coastguard Worker 
270*6777b538SAndroid Build Coastguard Worker   RepeatingTimer(const RepeatingTimer&) = delete;
271*6777b538SAndroid Build Coastguard Worker   RepeatingTimer& operator=(const RepeatingTimer&) = delete;
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker   ~RepeatingTimer() override;
274*6777b538SAndroid Build Coastguard Worker 
275*6777b538SAndroid Build Coastguard Worker   RepeatingTimer(const Location& posted_from,
276*6777b538SAndroid Build Coastguard Worker                  TimeDelta delay,
277*6777b538SAndroid Build Coastguard Worker                  RepeatingClosure user_task);
278*6777b538SAndroid Build Coastguard Worker   RepeatingTimer(const Location& posted_from,
279*6777b538SAndroid Build Coastguard Worker                  TimeDelta delay,
280*6777b538SAndroid Build Coastguard Worker                  RepeatingClosure user_task,
281*6777b538SAndroid Build Coastguard Worker                  const TickClock* tick_clock);
282*6777b538SAndroid Build Coastguard Worker 
283*6777b538SAndroid Build Coastguard Worker   // Start the timer to run at the given |delay| from now. If the timer is
284*6777b538SAndroid Build Coastguard Worker   // already running, it will be replaced to call the given |user_task|.
285*6777b538SAndroid Build Coastguard Worker   virtual void Start(const Location& posted_from,
286*6777b538SAndroid Build Coastguard Worker                      TimeDelta delay,
287*6777b538SAndroid Build Coastguard Worker                      RepeatingClosure user_task);
288*6777b538SAndroid Build Coastguard Worker 
289*6777b538SAndroid Build Coastguard Worker   // Start the timer to run at the given |delay| from now. If the timer is
290*6777b538SAndroid Build Coastguard Worker   // already running, it will be replaced to call a task formed from
291*6777b538SAndroid Build Coastguard Worker   // |receiver->*method|.
292*6777b538SAndroid Build Coastguard Worker   template <class Receiver>
Start(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)())293*6777b538SAndroid Build Coastguard Worker   void Start(const Location& posted_from,
294*6777b538SAndroid Build Coastguard Worker              TimeDelta delay,
295*6777b538SAndroid Build Coastguard Worker              Receiver* receiver,
296*6777b538SAndroid Build Coastguard Worker              void (Receiver::*method)()) {
297*6777b538SAndroid Build Coastguard Worker     Start(posted_from, delay, BindRepeating(method, Unretained(receiver)));
298*6777b538SAndroid Build Coastguard Worker   }
299*6777b538SAndroid Build Coastguard Worker 
user_task()300*6777b538SAndroid Build Coastguard Worker   const RepeatingClosure& user_task() const { return user_task_; }
301*6777b538SAndroid Build Coastguard Worker 
302*6777b538SAndroid Build Coastguard Worker  private:
303*6777b538SAndroid Build Coastguard Worker   // Mark this final, so that the destructor can call this safely.
304*6777b538SAndroid Build Coastguard Worker   void OnStop() final;
305*6777b538SAndroid Build Coastguard Worker   void RunUserTask() override;
306*6777b538SAndroid Build Coastguard Worker   void EnsureNonNullUserTask() final;
307*6777b538SAndroid Build Coastguard Worker 
308*6777b538SAndroid Build Coastguard Worker   RepeatingClosure user_task_;
309*6777b538SAndroid Build Coastguard Worker };
310*6777b538SAndroid Build Coastguard Worker 
311*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
312*6777b538SAndroid Build Coastguard Worker // A simple, one-shot timer with the retained |user_task| which is reused when
313*6777b538SAndroid Build Coastguard Worker // Reset() is invoked. See usage notes at the top of the file.
314*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT RetainingOneShotTimer : public internal::DelayTimerBase {
315*6777b538SAndroid Build Coastguard Worker  public:
316*6777b538SAndroid Build Coastguard Worker   RetainingOneShotTimer();
317*6777b538SAndroid Build Coastguard Worker   explicit RetainingOneShotTimer(const TickClock* tick_clock);
318*6777b538SAndroid Build Coastguard Worker 
319*6777b538SAndroid Build Coastguard Worker   RetainingOneShotTimer(const RetainingOneShotTimer&) = delete;
320*6777b538SAndroid Build Coastguard Worker   RetainingOneShotTimer& operator=(const RetainingOneShotTimer&) = delete;
321*6777b538SAndroid Build Coastguard Worker 
322*6777b538SAndroid Build Coastguard Worker   ~RetainingOneShotTimer() override;
323*6777b538SAndroid Build Coastguard Worker 
324*6777b538SAndroid Build Coastguard Worker   RetainingOneShotTimer(const Location& posted_from,
325*6777b538SAndroid Build Coastguard Worker                         TimeDelta delay,
326*6777b538SAndroid Build Coastguard Worker                         RepeatingClosure user_task);
327*6777b538SAndroid Build Coastguard Worker   RetainingOneShotTimer(const Location& posted_from,
328*6777b538SAndroid Build Coastguard Worker                         TimeDelta delay,
329*6777b538SAndroid Build Coastguard Worker                         RepeatingClosure user_task,
330*6777b538SAndroid Build Coastguard Worker                         const TickClock* tick_clock);
331*6777b538SAndroid Build Coastguard Worker 
332*6777b538SAndroid Build Coastguard Worker   // Start the timer to run at the given |delay| from now. If the timer is
333*6777b538SAndroid Build Coastguard Worker   // already running, it will be replaced to call the given |user_task|.
334*6777b538SAndroid Build Coastguard Worker   virtual void Start(const Location& posted_from,
335*6777b538SAndroid Build Coastguard Worker                      TimeDelta delay,
336*6777b538SAndroid Build Coastguard Worker                      RepeatingClosure user_task);
337*6777b538SAndroid Build Coastguard Worker 
338*6777b538SAndroid Build Coastguard Worker   // Start the timer to run at the given |delay| from now. If the timer is
339*6777b538SAndroid Build Coastguard Worker   // already running, it will be replaced to call a task formed from
340*6777b538SAndroid Build Coastguard Worker   // |receiver->*method|.
341*6777b538SAndroid Build Coastguard Worker   template <class Receiver>
Start(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)())342*6777b538SAndroid Build Coastguard Worker   void Start(const Location& posted_from,
343*6777b538SAndroid Build Coastguard Worker              TimeDelta delay,
344*6777b538SAndroid Build Coastguard Worker              Receiver* receiver,
345*6777b538SAndroid Build Coastguard Worker              void (Receiver::*method)()) {
346*6777b538SAndroid Build Coastguard Worker     Start(posted_from, delay, BindRepeating(method, Unretained(receiver)));
347*6777b538SAndroid Build Coastguard Worker   }
348*6777b538SAndroid Build Coastguard Worker 
user_task()349*6777b538SAndroid Build Coastguard Worker   const RepeatingClosure& user_task() const { return user_task_; }
350*6777b538SAndroid Build Coastguard Worker 
351*6777b538SAndroid Build Coastguard Worker  private:
352*6777b538SAndroid Build Coastguard Worker   // Mark this final, so that the destructor can call this safely.
353*6777b538SAndroid Build Coastguard Worker   void OnStop() final;
354*6777b538SAndroid Build Coastguard Worker   void RunUserTask() override;
355*6777b538SAndroid Build Coastguard Worker   void EnsureNonNullUserTask() final;
356*6777b538SAndroid Build Coastguard Worker 
357*6777b538SAndroid Build Coastguard Worker   RepeatingClosure user_task_;
358*6777b538SAndroid Build Coastguard Worker };
359*6777b538SAndroid Build Coastguard Worker 
360*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
361*6777b538SAndroid Build Coastguard Worker // A Delay timer is like The Button from Lost. Once started, you have to keep
362*6777b538SAndroid Build Coastguard Worker // calling Reset otherwise it will call the given method on the sequence it was
363*6777b538SAndroid Build Coastguard Worker // initially Reset() from.
364*6777b538SAndroid Build Coastguard Worker //
365*6777b538SAndroid Build Coastguard Worker // Once created, it is inactive until Reset is called. Once |delay| seconds have
366*6777b538SAndroid Build Coastguard Worker // passed since the last call to Reset, the callback is made. Once the callback
367*6777b538SAndroid Build Coastguard Worker // has been made, it's inactive until Reset is called again.
368*6777b538SAndroid Build Coastguard Worker //
369*6777b538SAndroid Build Coastguard Worker // If destroyed, the timeout is canceled and will not occur even if already
370*6777b538SAndroid Build Coastguard Worker // inflight.
371*6777b538SAndroid Build Coastguard Worker class DelayTimer {
372*6777b538SAndroid Build Coastguard Worker  public:
373*6777b538SAndroid Build Coastguard Worker   template <class Receiver>
DelayTimer(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)())374*6777b538SAndroid Build Coastguard Worker   DelayTimer(const Location& posted_from,
375*6777b538SAndroid Build Coastguard Worker              TimeDelta delay,
376*6777b538SAndroid Build Coastguard Worker              Receiver* receiver,
377*6777b538SAndroid Build Coastguard Worker              void (Receiver::*method)())
378*6777b538SAndroid Build Coastguard Worker       : DelayTimer(posted_from, delay, receiver, method, nullptr) {}
379*6777b538SAndroid Build Coastguard Worker 
380*6777b538SAndroid Build Coastguard Worker   template <class Receiver>
DelayTimer(const Location & posted_from,TimeDelta delay,Receiver * receiver,void (Receiver::* method)(),const TickClock * tick_clock)381*6777b538SAndroid Build Coastguard Worker   DelayTimer(const Location& posted_from,
382*6777b538SAndroid Build Coastguard Worker              TimeDelta delay,
383*6777b538SAndroid Build Coastguard Worker              Receiver* receiver,
384*6777b538SAndroid Build Coastguard Worker              void (Receiver::*method)(),
385*6777b538SAndroid Build Coastguard Worker              const TickClock* tick_clock)
386*6777b538SAndroid Build Coastguard Worker       : timer_(posted_from,
387*6777b538SAndroid Build Coastguard Worker                delay,
388*6777b538SAndroid Build Coastguard Worker                BindRepeating(method, Unretained(receiver)),
389*6777b538SAndroid Build Coastguard Worker                tick_clock) {}
390*6777b538SAndroid Build Coastguard Worker 
391*6777b538SAndroid Build Coastguard Worker   DelayTimer(const DelayTimer&) = delete;
392*6777b538SAndroid Build Coastguard Worker   DelayTimer& operator=(const DelayTimer&) = delete;
393*6777b538SAndroid Build Coastguard Worker 
Reset()394*6777b538SAndroid Build Coastguard Worker   void Reset() { timer_.Reset(); }
395*6777b538SAndroid Build Coastguard Worker 
396*6777b538SAndroid Build Coastguard Worker  private:
397*6777b538SAndroid Build Coastguard Worker   RetainingOneShotTimer timer_;
398*6777b538SAndroid Build Coastguard Worker };
399*6777b538SAndroid Build Coastguard Worker 
400*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
401*6777b538SAndroid Build Coastguard Worker // A one-shot timer that attempts to run |user_task| some time near specified
402*6777b538SAndroid Build Coastguard Worker // deadline. See usage notes at the top of the file.
403*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT DeadlineTimer : public internal::TimerBase {
404*6777b538SAndroid Build Coastguard Worker  public:
405*6777b538SAndroid Build Coastguard Worker   DeadlineTimer();
406*6777b538SAndroid Build Coastguard Worker   ~DeadlineTimer() override;
407*6777b538SAndroid Build Coastguard Worker 
408*6777b538SAndroid Build Coastguard Worker   DeadlineTimer(const DeadlineTimer&) = delete;
409*6777b538SAndroid Build Coastguard Worker   DeadlineTimer& operator=(const DeadlineTimer&) = delete;
410*6777b538SAndroid Build Coastguard Worker 
411*6777b538SAndroid Build Coastguard Worker   // Start the timer to run |user_task| near the specified |deadline| following
412*6777b538SAndroid Build Coastguard Worker   // |delay_policy| If the timer is already running, it will be replaced to call
413*6777b538SAndroid Build Coastguard Worker   // the given |user_task|.
414*6777b538SAndroid Build Coastguard Worker   void Start(const Location& posted_from,
415*6777b538SAndroid Build Coastguard Worker              TimeTicks deadline,
416*6777b538SAndroid Build Coastguard Worker              OnceClosure user_task,
417*6777b538SAndroid Build Coastguard Worker              subtle::DelayPolicy delay_policy =
418*6777b538SAndroid Build Coastguard Worker                  subtle::DelayPolicy::kFlexiblePreferEarly);
419*6777b538SAndroid Build Coastguard Worker 
420*6777b538SAndroid Build Coastguard Worker   // Start the timer to run |user_task| near the specified |deadline|. If the
421*6777b538SAndroid Build Coastguard Worker   // timer is already running, it will be replaced to call a task formed from
422*6777b538SAndroid Build Coastguard Worker   // |receiver->*method|.
423*6777b538SAndroid Build Coastguard Worker   template <class Receiver>
424*6777b538SAndroid Build Coastguard Worker   void Start(const Location& posted_from,
425*6777b538SAndroid Build Coastguard Worker              TimeTicks deadline,
426*6777b538SAndroid Build Coastguard Worker              Receiver* receiver,
427*6777b538SAndroid Build Coastguard Worker              void (Receiver::*method)(),
428*6777b538SAndroid Build Coastguard Worker              subtle::DelayPolicy delay_policy =
429*6777b538SAndroid Build Coastguard Worker                  subtle::DelayPolicy::kFlexiblePreferEarly) {
430*6777b538SAndroid Build Coastguard Worker     Start(posted_from, deadline, BindOnce(method, Unretained(receiver)),
431*6777b538SAndroid Build Coastguard Worker           delay_policy);
432*6777b538SAndroid Build Coastguard Worker   }
433*6777b538SAndroid Build Coastguard Worker 
434*6777b538SAndroid Build Coastguard Worker  protected:
435*6777b538SAndroid Build Coastguard Worker   void OnStop() override;
436*6777b538SAndroid Build Coastguard Worker 
437*6777b538SAndroid Build Coastguard Worker   // Schedules |OnScheduledTaskInvoked()| to run on the current sequence at
438*6777b538SAndroid Build Coastguard Worker   // the given |deadline|.
439*6777b538SAndroid Build Coastguard Worker   void ScheduleNewTask(TimeTicks deadline, subtle::DelayPolicy delay_policy);
440*6777b538SAndroid Build Coastguard Worker 
441*6777b538SAndroid Build Coastguard Worker  private:
442*6777b538SAndroid Build Coastguard Worker   // Called when the scheduled task is invoked to run the |user_task|.
443*6777b538SAndroid Build Coastguard Worker   void OnScheduledTaskInvoked();
444*6777b538SAndroid Build Coastguard Worker 
445*6777b538SAndroid Build Coastguard Worker   OnceClosure user_task_;
446*6777b538SAndroid Build Coastguard Worker };
447*6777b538SAndroid Build Coastguard Worker 
448*6777b538SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
449*6777b538SAndroid Build Coastguard Worker // Repeatedly invokes a callback, waiting for a precise delay between the
450*6777b538SAndroid Build Coastguard Worker // beginning of each invocation. See usage notes at the top of the file.
451*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT MetronomeTimer : public internal::TimerBase {
452*6777b538SAndroid Build Coastguard Worker  public:
453*6777b538SAndroid Build Coastguard Worker   MetronomeTimer();
454*6777b538SAndroid Build Coastguard Worker   ~MetronomeTimer() override;
455*6777b538SAndroid Build Coastguard Worker 
456*6777b538SAndroid Build Coastguard Worker   MetronomeTimer(const MetronomeTimer&) = delete;
457*6777b538SAndroid Build Coastguard Worker   MetronomeTimer& operator=(const MetronomeTimer&) = delete;
458*6777b538SAndroid Build Coastguard Worker 
459*6777b538SAndroid Build Coastguard Worker   MetronomeTimer(const Location& posted_from,
460*6777b538SAndroid Build Coastguard Worker                  TimeDelta interval,
461*6777b538SAndroid Build Coastguard Worker                  RepeatingClosure user_task,
462*6777b538SAndroid Build Coastguard Worker                  TimeTicks phase = TimeTicks());
463*6777b538SAndroid Build Coastguard Worker 
464*6777b538SAndroid Build Coastguard Worker   // Start the timer to repeatedly run |user_task| at the specified |interval|;
465*6777b538SAndroid Build Coastguard Worker   // If not specified, the phase is up to the scheduler, otherwise each
466*6777b538SAndroid Build Coastguard Worker   // invocation starts as close as possible to `phase + n * delay` for some
467*6777b538SAndroid Build Coastguard Worker   // integer n. If the timer is already running, it will be replaced to call the
468*6777b538SAndroid Build Coastguard Worker   // given |user_task|.
469*6777b538SAndroid Build Coastguard Worker   void Start(const Location& posted_from,
470*6777b538SAndroid Build Coastguard Worker              TimeDelta interval,
471*6777b538SAndroid Build Coastguard Worker              RepeatingClosure user_task,
472*6777b538SAndroid Build Coastguard Worker              TimeTicks phase = TimeTicks());
473*6777b538SAndroid Build Coastguard Worker 
474*6777b538SAndroid Build Coastguard Worker   // Same as the previous overload, except that the user task is specified by
475*6777b538SAndroid Build Coastguard Worker   // `receiver` and `method`.
476*6777b538SAndroid Build Coastguard Worker   template <class Receiver>
477*6777b538SAndroid Build Coastguard Worker   void Start(const Location& posted_from,
478*6777b538SAndroid Build Coastguard Worker              TimeDelta interval,
479*6777b538SAndroid Build Coastguard Worker              Receiver* receiver,
480*6777b538SAndroid Build Coastguard Worker              void (Receiver::*method)(),
481*6777b538SAndroid Build Coastguard Worker              TimeTicks phase = TimeTicks()) {
482*6777b538SAndroid Build Coastguard Worker     Start(posted_from, interval, BindRepeating(method, Unretained(receiver)),
483*6777b538SAndroid Build Coastguard Worker           phase);
484*6777b538SAndroid Build Coastguard Worker   }
485*6777b538SAndroid Build Coastguard Worker 
486*6777b538SAndroid Build Coastguard Worker   // Call this method to reset the timer delay. The user task must be set. If
487*6777b538SAndroid Build Coastguard Worker   // the timer is not running, this will start it by posting a task.
488*6777b538SAndroid Build Coastguard Worker   void Reset();
489*6777b538SAndroid Build Coastguard Worker 
490*6777b538SAndroid Build Coastguard Worker  protected:
491*6777b538SAndroid Build Coastguard Worker   void OnStop() override;
492*6777b538SAndroid Build Coastguard Worker 
493*6777b538SAndroid Build Coastguard Worker   // Schedules |OnScheduledTaskInvoked()| to run on the current sequence at
494*6777b538SAndroid Build Coastguard Worker   // the next tick.
495*6777b538SAndroid Build Coastguard Worker   void ScheduleNewTask();
496*6777b538SAndroid Build Coastguard Worker 
497*6777b538SAndroid Build Coastguard Worker  private:
498*6777b538SAndroid Build Coastguard Worker   // Called when the scheduled task is invoked to run the |user_task|.
499*6777b538SAndroid Build Coastguard Worker   void OnScheduledTaskInvoked();
500*6777b538SAndroid Build Coastguard Worker 
501*6777b538SAndroid Build Coastguard Worker   TimeDelta interval_;
502*6777b538SAndroid Build Coastguard Worker   RepeatingClosure user_task_;
503*6777b538SAndroid Build Coastguard Worker   TimeTicks phase_;
504*6777b538SAndroid Build Coastguard Worker };
505*6777b538SAndroid Build Coastguard Worker 
506*6777b538SAndroid Build Coastguard Worker }  // namespace base
507*6777b538SAndroid Build Coastguard Worker 
508*6777b538SAndroid Build Coastguard Worker #endif  // BASE_TIMER_TIMER_H_
509