Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: base/timer/timer.h

Issue 2484023002: Use a TickClock instead of TimeTicks::Now() in Timer. (Closed)
Patch Set: Added unit tests and removed Chrome OS changes. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/timer/timer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // OneShotTimer and RepeatingTimer provide a simple timer API. As the names 5 // OneShotTimer and RepeatingTimer provide a simple timer API. As the names
6 // suggest, OneShotTimer calls you back once after a time delay expires. 6 // suggest, OneShotTimer calls you back once after a time delay expires.
7 // RepeatingTimer on the other hand calls you back periodically with the 7 // RepeatingTimer on the other hand calls you back periodically with the
8 // prescribed time interval. 8 // prescribed time interval.
9 // 9 //
10 // OneShotTimer and RepeatingTimer both cancel the timer when they go out of 10 // OneShotTimer and RepeatingTimer both cancel the timer when they go out of
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 // NOTE: These APIs are not thread safe. Always call from the same thread. 42 // NOTE: These APIs are not thread safe. Always call from the same thread.
43 43
44 #ifndef BASE_TIMER_TIMER_H_ 44 #ifndef BASE_TIMER_TIMER_H_
45 #define BASE_TIMER_TIMER_H_ 45 #define BASE_TIMER_TIMER_H_
46 46
47 // IMPORTANT: If you change timer code, make sure that all tests (including 47 // IMPORTANT: If you change timer code, make sure that all tests (including
48 // disabled ones) from timer_unittests.cc pass locally. Some are disabled 48 // disabled ones) from timer_unittests.cc pass locally. Some are disabled
49 // because they're flaky on the buildbot, but when you run them locally you 49 // because they're flaky on the buildbot, but when you run them locally you
50 // should be able to tell the difference. 50 // should be able to tell the difference.
51 51
52 #include <memory>
53
52 #include "base/base_export.h" 54 #include "base/base_export.h"
53 #include "base/bind.h" 55 #include "base/bind.h"
54 #include "base/bind_helpers.h" 56 #include "base/bind_helpers.h"
55 #include "base/callback.h" 57 #include "base/callback.h"
56 #include "base/location.h" 58 #include "base/location.h"
57 #include "base/macros.h" 59 #include "base/macros.h"
58 #include "base/time/time.h" 60 #include "base/time/time.h"
59 61
60 namespace base { 62 namespace base {
61 63
62 class BaseTimerTaskInternal; 64 class BaseTimerTaskInternal;
63 class SingleThreadTaskRunner; 65 class SingleThreadTaskRunner;
66 class TickClock;
64 67
65 //----------------------------------------------------------------------------- 68 //-----------------------------------------------------------------------------
66 // This class wraps MessageLoop::PostDelayedTask to manage delayed and repeating 69 // This class wraps MessageLoop::PostDelayedTask to manage delayed and repeating
67 // tasks. It must be destructed on the same thread that starts tasks. There are 70 // tasks. It must be destructed on the same thread that starts tasks. There are
68 // DCHECKs in place to verify this. 71 // DCHECKs in place to verify this.
69 // 72 //
70 class BASE_EXPORT Timer { 73 class BASE_EXPORT Timer {
71 public: 74 public:
72 // Construct a timer in repeating or one-shot mode. Start or SetTaskInfo must 75 // Construct a timer in repeating or one-shot mode. Start or SetTaskInfo must
73 // be called later to set task info. |retain_user_task| determines whether the 76 // be called later to set task info. |retain_user_task| determines whether the
74 // user_task is retained or reset when it runs or stops. 77 // user_task is retained or reset when it runs or stops. If |tick_clock| is
78 // provided, it is used instead of TimeTicks::Now() to get TimeTicks when
79 // scheduling tasks.
75 Timer(bool retain_user_task, bool is_repeating); 80 Timer(bool retain_user_task, bool is_repeating);
81 Timer(bool retain_user_task, bool is_repeating, TickClock* tick_clock);
76 82
77 // Construct a timer with retained task info. 83 // Construct a timer with retained task info. If |tick_clock| is provided, it
84 // is used instead of TimeTicks::Now() to get TimeTicks when scheduling tasks.
78 Timer(const tracked_objects::Location& posted_from, 85 Timer(const tracked_objects::Location& posted_from,
79 TimeDelta delay, 86 TimeDelta delay,
80 const base::Closure& user_task, 87 const base::Closure& user_task,
81 bool is_repeating); 88 bool is_repeating);
89 Timer(const tracked_objects::Location& posted_from,
90 TimeDelta delay,
91 const base::Closure& user_task,
92 bool is_repeating,
93 TickClock* tick_clock);
82 94
83 virtual ~Timer(); 95 virtual ~Timer();
84 96
85 // Returns true if the timer is running (i.e., not stopped). 97 // Returns true if the timer is running (i.e., not stopped).
86 virtual bool IsRunning() const; 98 virtual bool IsRunning() const;
87 99
88 // Returns the current delay for this timer. 100 // Returns the current delay for this timer.
89 virtual TimeDelta GetCurrentDelay() const; 101 virtual TimeDelta GetCurrentDelay() const;
90 102
91 // Set the task runner on which the task should be scheduled. This method can 103 // Set the task runner on which the task should be scheduled. This method can
(...skipping 12 matching lines...) Expand all
104 virtual void Stop(); 116 virtual void Stop();
105 117
106 // Call this method to reset the timer delay. The user_task_ must be set. If 118 // Call this method to reset the timer delay. The user_task_ must be set. If
107 // the timer is not running, this will start it by posting a task. 119 // the timer is not running, this will start it by posting a task.
108 virtual void Reset(); 120 virtual void Reset();
109 121
110 const base::Closure& user_task() const { return user_task_; } 122 const base::Closure& user_task() const { return user_task_; }
111 const TimeTicks& desired_run_time() const { return desired_run_time_; } 123 const TimeTicks& desired_run_time() const { return desired_run_time_; }
112 124
113 protected: 125 protected:
126 // Returns the current tick count.
127 TimeTicks Now() const;
128
114 // Used to initiate a new delayed task. This has the side-effect of disabling 129 // Used to initiate a new delayed task. This has the side-effect of disabling
115 // scheduled_task_ if it is non-null. 130 // scheduled_task_ if it is non-null.
116 void SetTaskInfo(const tracked_objects::Location& posted_from, 131 void SetTaskInfo(const tracked_objects::Location& posted_from,
117 TimeDelta delay, 132 TimeDelta delay,
118 const base::Closure& user_task); 133 const base::Closure& user_task);
119 134
120 void set_user_task(const Closure& task) { user_task_ = task; } 135 void set_user_task(const Closure& task) { user_task_ = task; }
121 void set_desired_run_time(TimeTicks desired) { desired_run_time_ = desired; } 136 void set_desired_run_time(TimeTicks desired) { desired_run_time_ = desired; }
122 void set_is_running(bool running) { is_running_ = running; } 137 void set_is_running(bool running) { is_running_ = running; }
123 138
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 // Thread ID of current MessageLoop for verifying single-threaded usage. 199 // Thread ID of current MessageLoop for verifying single-threaded usage.
185 int thread_id_; 200 int thread_id_;
186 201
187 // Repeating timers automatically post the task again before calling the task 202 // Repeating timers automatically post the task again before calling the task
188 // callback. 203 // callback.
189 const bool is_repeating_; 204 const bool is_repeating_;
190 205
191 // If true, hold on to the user_task_ closure object for reuse. 206 // If true, hold on to the user_task_ closure object for reuse.
192 const bool retain_user_task_; 207 const bool retain_user_task_;
193 208
209 // The tick clock used to calculate the run time for scheduled tasks.
210 TickClock* const tick_clock_;
211
194 // If true, user_task_ is scheduled to run sometime in the future. 212 // If true, user_task_ is scheduled to run sometime in the future.
195 bool is_running_; 213 bool is_running_;
196 214
197 DISALLOW_COPY_AND_ASSIGN(Timer); 215 DISALLOW_COPY_AND_ASSIGN(Timer);
198 }; 216 };
199 217
200 //----------------------------------------------------------------------------- 218 //-----------------------------------------------------------------------------
201 // This class is an implementation detail of OneShotTimer and RepeatingTimer. 219 // This class is an implementation detail of OneShotTimer and RepeatingTimer.
202 // Please do not use this class directly. 220 // Please do not use this class directly.
203 class BaseTimerMethodPointer : public Timer { 221 class BaseTimerMethodPointer : public Timer {
204 public: 222 public:
205 // This is here to work around the fact that Timer::Start is "hidden" by the 223 // This is here to work around the fact that Timer::Start is "hidden" by the
206 // Start definition below, rather than being overloaded. 224 // Start definition below, rather than being overloaded.
207 // TODO(tim): We should remove uses of BaseTimerMethodPointer::Start below 225 // TODO(tim): We should remove uses of BaseTimerMethodPointer::Start below
208 // and convert callers to use the base::Closure version in Timer::Start, 226 // and convert callers to use the base::Closure version in Timer::Start,
209 // see bug 148832. 227 // see bug 148832.
210 using Timer::Start; 228 using Timer::Start;
211 229
212 enum RepeatMode { ONE_SHOT, REPEATING }; 230 enum RepeatMode { ONE_SHOT, REPEATING };
213 BaseTimerMethodPointer(RepeatMode mode) 231 BaseTimerMethodPointer(RepeatMode mode, TickClock* tick_clock)
214 : Timer(mode == REPEATING, mode == REPEATING) {} 232 : Timer(mode == REPEATING, mode == REPEATING, tick_clock) {}
215 233
216 // Start the timer to run at the given |delay| from now. If the timer is 234 // Start the timer to run at the given |delay| from now. If the timer is
217 // already running, it will be replaced to call a task formed from 235 // already running, it will be replaced to call a task formed from
218 // |reviewer->*method|. 236 // |reviewer->*method|.
219 template <class Receiver> 237 template <class Receiver>
220 void Start(const tracked_objects::Location& posted_from, 238 void Start(const tracked_objects::Location& posted_from,
221 TimeDelta delay, 239 TimeDelta delay,
222 Receiver* receiver, 240 Receiver* receiver,
223 void (Receiver::*method)()) { 241 void (Receiver::*method)()) {
224 Timer::Start(posted_from, delay, 242 Timer::Start(posted_from, delay,
225 base::Bind(method, base::Unretained(receiver))); 243 base::Bind(method, base::Unretained(receiver)));
226 } 244 }
227 }; 245 };
228 246
229 //----------------------------------------------------------------------------- 247 //-----------------------------------------------------------------------------
230 // A simple, one-shot timer. See usage notes at the top of the file. 248 // A simple, one-shot timer. See usage notes at the top of the file.
231 class OneShotTimer : public BaseTimerMethodPointer { 249 class OneShotTimer : public BaseTimerMethodPointer {
232 public: 250 public:
233 OneShotTimer() : BaseTimerMethodPointer(ONE_SHOT) {} 251 OneShotTimer() : OneShotTimer(nullptr) {}
252 explicit OneShotTimer(TickClock* tick_clock)
253 : BaseTimerMethodPointer(ONE_SHOT, tick_clock) {}
234 }; 254 };
235 255
236 //----------------------------------------------------------------------------- 256 //-----------------------------------------------------------------------------
237 // A simple, repeating timer. See usage notes at the top of the file. 257 // A simple, repeating timer. See usage notes at the top of the file.
238 class RepeatingTimer : public BaseTimerMethodPointer { 258 class RepeatingTimer : public BaseTimerMethodPointer {
239 public: 259 public:
240 RepeatingTimer() : BaseTimerMethodPointer(REPEATING) {} 260 RepeatingTimer() : RepeatingTimer(nullptr) {}
261 explicit RepeatingTimer(TickClock* tick_clock)
262 : BaseTimerMethodPointer(REPEATING, tick_clock) {}
241 }; 263 };
242 264
243 //----------------------------------------------------------------------------- 265 //-----------------------------------------------------------------------------
244 // A Delay timer is like The Button from Lost. Once started, you have to keep 266 // A Delay timer is like The Button from Lost. Once started, you have to keep
245 // calling Reset otherwise it will call the given method in the MessageLoop 267 // calling Reset otherwise it will call the given method in the MessageLoop
246 // thread. 268 // thread.
247 // 269 //
248 // Once created, it is inactive until Reset is called. Once |delay| seconds have 270 // Once created, it is inactive until Reset is called. Once |delay| seconds have
249 // passed since the last call to Reset, the callback is made. Once the callback 271 // passed since the last call to Reset, the callback is made. Once the callback
250 // has been made, it's inactive until Reset is called again. 272 // has been made, it's inactive until Reset is called again.
251 // 273 //
252 // If destroyed, the timeout is canceled and will not occur even if already 274 // If destroyed, the timeout is canceled and will not occur even if already
253 // inflight. 275 // inflight.
254 class DelayTimer : protected Timer { 276 class DelayTimer : protected Timer {
255 public: 277 public:
256 template <class Receiver> 278 template <class Receiver>
257 DelayTimer(const tracked_objects::Location& posted_from, 279 DelayTimer(const tracked_objects::Location& posted_from,
258 TimeDelta delay, 280 TimeDelta delay,
259 Receiver* receiver, 281 Receiver* receiver,
260 void (Receiver::*method)()) 282 void (Receiver::*method)())
283 : DelayTimer(posted_from, delay, receiver, method, nullptr) {}
284
285 template <class Receiver>
286 DelayTimer(const tracked_objects::Location& posted_from,
287 TimeDelta delay,
288 Receiver* receiver,
289 void (Receiver::*method)(),
290 TickClock* tick_clock)
261 : Timer(posted_from, 291 : Timer(posted_from,
262 delay, 292 delay,
263 base::Bind(method, base::Unretained(receiver)), 293 base::Bind(method, base::Unretained(receiver)),
264 false) {} 294 false,
295 tick_clock) {}
265 296
266 void Reset() override; 297 void Reset() override;
267 }; 298 };
268 299
269 // This class has a templated method so it can not be exported without failing 300 // This class has a templated method so it can not be exported without failing
270 // to link in MSVC. But clang-plugin does not allow inline definitions of 301 // to link in MSVC. But clang-plugin does not allow inline definitions of
271 // virtual methods, so the inline definition lives in the header file here 302 // virtual methods, so the inline definition lives in the header file here
272 // to satisfy both. 303 // to satisfy both.
273 inline void DelayTimer::Reset() { 304 inline void DelayTimer::Reset() {
274 Timer::Reset(); 305 Timer::Reset();
275 } 306 }
276 307
277 } // namespace base 308 } // namespace base
278 309
279 #endif // BASE_TIMER_TIMER_H_ 310 #endif // BASE_TIMER_TIMER_H_
OLDNEW
« no previous file with comments | « no previous file | base/timer/timer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698