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

Side by Side Diff: base/timer.h

Issue 7825026: Revert "Currently, base/timer.cc calls PostTask with FROM_HERE as the Location, (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 3 months 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 | Annotate | Revision Log
« no previous file with comments | « base/system_monitor/system_monitor.cc ('k') | base/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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 DCHECK(IsRunning()); 80 DCHECK(IsRunning());
81 return delayed_task_->delay_; 81 return delayed_task_->delay_;
82 } 82 }
83 83
84 protected: 84 protected:
85 BaseTimer_Helper() : delayed_task_(NULL) {} 85 BaseTimer_Helper() : delayed_task_(NULL) {}
86 86
87 // We have access to the timer_ member so we can orphan this task. 87 // We have access to the timer_ member so we can orphan this task.
88 class TimerTask : public Task { 88 class TimerTask : public Task {
89 public: 89 public:
90 TimerTask(const tracked_objects::Location& posted_from, 90 explicit TimerTask(TimeDelta delay) : timer_(NULL), delay_(delay) {
91 TimeDelta delay)
92 : posted_from_(posted_from),
93 timer_(NULL),
94 delay_(delay) {
95 } 91 }
96 virtual ~TimerTask() {} 92 virtual ~TimerTask() {}
97 tracked_objects::Location posted_from_;
98 BaseTimer_Helper* timer_; 93 BaseTimer_Helper* timer_;
99 TimeDelta delay_; 94 TimeDelta delay_;
100 }; 95 };
101 96
102 // Used to orphan delayed_task_ so that when it runs it does nothing. 97 // Used to orphan delayed_task_ so that when it runs it does nothing.
103 void OrphanDelayedTask(); 98 void OrphanDelayedTask();
104 99
105 // Used to initiated a new delayed task. This has the side-effect of 100 // Used to initiated a new delayed task. This has the side-effect of
106 // orphaning delayed_task_ if it is non-null. 101 // orphaning delayed_task_ if it is non-null.
107 void InitiateDelayedTask(TimerTask* timer_task); 102 void InitiateDelayedTask(TimerTask* timer_task);
108 103
109 TimerTask* delayed_task_; 104 TimerTask* delayed_task_;
110 105
111 DISALLOW_COPY_AND_ASSIGN(BaseTimer_Helper); 106 DISALLOW_COPY_AND_ASSIGN(BaseTimer_Helper);
112 }; 107 };
113 108
114 //----------------------------------------------------------------------------- 109 //-----------------------------------------------------------------------------
115 // This class is an implementation detail of OneShotTimer and RepeatingTimer. 110 // This class is an implementation detail of OneShotTimer and RepeatingTimer.
116 // Please do not use this class directly. 111 // Please do not use this class directly.
117 template <class Receiver, bool kIsRepeating> 112 template <class Receiver, bool kIsRepeating>
118 class BaseTimer : public BaseTimer_Helper { 113 class BaseTimer : public BaseTimer_Helper {
119 public: 114 public:
120 typedef void (Receiver::*ReceiverMethod)(); 115 typedef void (Receiver::*ReceiverMethod)();
121 116
122 // Call this method to start the timer. It is an error to call this method 117 // Call this method to start the timer. It is an error to call this method
123 // while the timer is already running. 118 // while the timer is already running.
124 void Start(const tracked_objects::Location& posted_from, 119 void Start(TimeDelta delay, Receiver* receiver, ReceiverMethod method) {
125 TimeDelta delay,
126 Receiver* receiver,
127 ReceiverMethod method) {
128 DCHECK(!IsRunning()); 120 DCHECK(!IsRunning());
129 InitiateDelayedTask(new TimerTask(posted_from, delay, receiver, method)); 121 InitiateDelayedTask(new TimerTask(delay, receiver, method));
130 } 122 }
131 123
132 // Call this method to stop the timer. It is a no-op if the timer is not 124 // Call this method to stop the timer. It is a no-op if the timer is not
133 // running. 125 // running.
134 void Stop() { 126 void Stop() {
135 OrphanDelayedTask(); 127 OrphanDelayedTask();
136 } 128 }
137 129
138 // Call this method to reset the timer delay of an already running timer. 130 // Call this method to reset the timer delay of an already running timer.
139 void Reset() { 131 void Reset() {
140 DCHECK(IsRunning()); 132 DCHECK(IsRunning());
141 InitiateDelayedTask(static_cast<TimerTask*>(delayed_task_)->Clone()); 133 InitiateDelayedTask(static_cast<TimerTask*>(delayed_task_)->Clone());
142 } 134 }
143 135
144 private: 136 private:
145 typedef BaseTimer<Receiver, kIsRepeating> SelfType; 137 typedef BaseTimer<Receiver, kIsRepeating> SelfType;
146 138
147 class TimerTask : public BaseTimer_Helper::TimerTask { 139 class TimerTask : public BaseTimer_Helper::TimerTask {
148 public: 140 public:
149 TimerTask(const tracked_objects::Location& posted_from, 141 TimerTask(TimeDelta delay, Receiver* receiver, ReceiverMethod method)
150 TimeDelta delay, 142 : BaseTimer_Helper::TimerTask(delay),
151 Receiver* receiver,
152 ReceiverMethod method)
153 : BaseTimer_Helper::TimerTask(posted_from, delay),
154 receiver_(receiver), 143 receiver_(receiver),
155 method_(method) { 144 method_(method) {
156 } 145 }
157 146
158 virtual ~TimerTask() { 147 virtual ~TimerTask() {
159 // This task may be getting cleared because the MessageLoop has been 148 // This task may be getting cleared because the MessageLoop has been
160 // destructed. If so, don't leave the Timer with a dangling pointer 149 // destructed. If so, don't leave the Timer with a dangling pointer
161 // to this now-defunct task. 150 // to this now-defunct task.
162 ClearBaseTimer(); 151 ClearBaseTimer();
163 } 152 }
164 153
165 virtual void Run() { 154 virtual void Run() {
166 if (!timer_) // timer_ is null if we were orphaned. 155 if (!timer_) // timer_ is null if we were orphaned.
167 return; 156 return;
168 if (kIsRepeating) 157 if (kIsRepeating)
169 ResetBaseTimer(); 158 ResetBaseTimer();
170 else 159 else
171 ClearBaseTimer(); 160 ClearBaseTimer();
172 DispatchToMethod(receiver_, method_, Tuple0()); 161 DispatchToMethod(receiver_, method_, Tuple0());
173 } 162 }
174 163
175 TimerTask* Clone() const { 164 TimerTask* Clone() const {
176 return new TimerTask(posted_from_, delay_, receiver_, method_); 165 return new TimerTask(delay_, receiver_, method_);
177 } 166 }
178 167
179 private: 168 private:
180 // Inform the Base that the timer is no longer active. 169 // Inform the Base that the timer is no longer active.
181 void ClearBaseTimer() { 170 void ClearBaseTimer() {
182 if (timer_) { 171 if (timer_) {
183 SelfType* self = static_cast<SelfType*>(timer_); 172 SelfType* self = static_cast<SelfType*>(timer_);
184 // It is possible that the Timer has already been reset, and that this 173 // It is possible that the Timer has already been reset, and that this
185 // Task is old. So, if the Timer points to a different task, assume 174 // Task is old. So, if the Timer points to a different task, assume
186 // that the Timer has already taken care of properly setting the task. 175 // that the Timer has already taken care of properly setting the task.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 // passed since the last call to Reset, the callback is made. Once the callback 214 // passed since the last call to Reset, the callback is made. Once the callback
226 // has been made, it's inactive until Reset is called again. 215 // has been made, it's inactive until Reset is called again.
227 // 216 //
228 // If destroyed, the timeout is canceled and will not occur even if already 217 // If destroyed, the timeout is canceled and will not occur even if already
229 // inflight. 218 // inflight.
230 template <class Receiver> 219 template <class Receiver>
231 class DelayTimer { 220 class DelayTimer {
232 public: 221 public:
233 typedef void (Receiver::*ReceiverMethod)(); 222 typedef void (Receiver::*ReceiverMethod)();
234 223
235 DelayTimer(const tracked_objects::Location& posted_from, 224 DelayTimer(TimeDelta delay, Receiver* receiver, ReceiverMethod method)
236 TimeDelta delay, 225 : receiver_(receiver),
237 Receiver* receiver,
238 ReceiverMethod method)
239 : posted_from_(posted_from),
240 receiver_(receiver),
241 method_(method), 226 method_(method),
242 delay_(delay) { 227 delay_(delay) {
243 } 228 }
244 229
245 void Reset() { 230 void Reset() {
246 DelayFor(delay_); 231 DelayFor(delay_);
247 } 232 }
248 233
249 private: 234 private:
250 void DelayFor(TimeDelta delay) { 235 void DelayFor(TimeDelta delay) {
251 trigger_time_ = TimeTicks::Now() + delay; 236 trigger_time_ = TimeTicks::Now() + delay;
252 237
253 // If we already have a timer that will expire at or before the given delay, 238 // If we already have a timer that will expire at or before the given delay,
254 // then we have nothing more to do now. 239 // then we have nothing more to do now.
255 if (timer_.IsRunning() && timer_.GetCurrentDelay() <= delay) 240 if (timer_.IsRunning() && timer_.GetCurrentDelay() <= delay)
256 return; 241 return;
257 242
258 // The timer isn't running, or will expire too late, so restart it. 243 // The timer isn't running, or will expire too late, so restart it.
259 timer_.Stop(); 244 timer_.Stop();
260 timer_.Start(posted_from_, delay, this, &DelayTimer<Receiver>::Check); 245 timer_.Start(delay, this, &DelayTimer<Receiver>::Check);
261 } 246 }
262 247
263 void Check() { 248 void Check() {
264 if (trigger_time_.is_null()) 249 if (trigger_time_.is_null())
265 return; 250 return;
266 251
267 // If we have not waited long enough, then wait some more. 252 // If we have not waited long enough, then wait some more.
268 const TimeTicks now = TimeTicks::Now(); 253 const TimeTicks now = TimeTicks::Now();
269 if (now < trigger_time_) { 254 if (now < trigger_time_) {
270 DelayFor(trigger_time_ - now); 255 DelayFor(trigger_time_ - now);
271 return; 256 return;
272 } 257 }
273 258
274 (receiver_->*method_)(); 259 (receiver_->*method_)();
275 } 260 }
276 261
277 tracked_objects::Location posted_from_;
278 Receiver *const receiver_; 262 Receiver *const receiver_;
279 const ReceiverMethod method_; 263 const ReceiverMethod method_;
280 const TimeDelta delay_; 264 const TimeDelta delay_;
281 265
282 OneShotTimer<DelayTimer<Receiver> > timer_; 266 OneShotTimer<DelayTimer<Receiver> > timer_;
283 TimeTicks trigger_time_; 267 TimeTicks trigger_time_;
284 }; 268 };
285 269
286 } // namespace base 270 } // namespace base
287 271
288 #endif // BASE_TIMER_H_ 272 #endif // BASE_TIMER_H_
OLDNEW
« no previous file with comments | « base/system_monitor/system_monitor.cc ('k') | base/timer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698