OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 | 75 |
76 protected: | 76 protected: |
77 BaseTimer_Helper() : delayed_task_(NULL) {} | 77 BaseTimer_Helper() : delayed_task_(NULL) {} |
78 | 78 |
79 // We have access to the timer_ member so we can orphan this task. | 79 // We have access to the timer_ member so we can orphan this task. |
80 class TimerTask : public Task { | 80 class TimerTask : public Task { |
81 public: | 81 public: |
82 TimerTask(TimeDelta delay) : delay_(delay) { | 82 TimerTask(TimeDelta delay) : delay_(delay) { |
83 // timer_ is set in InitiateDelayedTask. | 83 // timer_ is set in InitiateDelayedTask. |
84 } | 84 } |
| 85 virtual ~TimerTask() {} |
85 BaseTimer_Helper* timer_; | 86 BaseTimer_Helper* timer_; |
86 TimeDelta delay_; | 87 TimeDelta delay_; |
87 }; | 88 }; |
88 | 89 |
89 // Used to orphan delayed_task_ so that when it runs it does nothing. | 90 // Used to orphan delayed_task_ so that when it runs it does nothing. |
90 void OrphanDelayedTask(); | 91 void OrphanDelayedTask(); |
91 | 92 |
92 // Used to initiated a new delayed task. This has the side-effect of | 93 // Used to initiated a new delayed task. This has the side-effect of |
93 // orphaning delayed_task_ if it is non-null. | 94 // orphaning delayed_task_ if it is non-null. |
94 void InitiateDelayedTask(TimerTask* timer_task); | 95 void InitiateDelayedTask(TimerTask* timer_task); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 private: | 129 private: |
129 typedef BaseTimer<Receiver, kIsRepeating> SelfType; | 130 typedef BaseTimer<Receiver, kIsRepeating> SelfType; |
130 | 131 |
131 class TimerTask : public BaseTimer_Helper::TimerTask { | 132 class TimerTask : public BaseTimer_Helper::TimerTask { |
132 public: | 133 public: |
133 TimerTask(TimeDelta delay, Receiver* receiver, ReceiverMethod method) | 134 TimerTask(TimeDelta delay, Receiver* receiver, ReceiverMethod method) |
134 : BaseTimer_Helper::TimerTask(delay), | 135 : BaseTimer_Helper::TimerTask(delay), |
135 receiver_(receiver), | 136 receiver_(receiver), |
136 method_(method) { | 137 method_(method) { |
137 } | 138 } |
| 139 |
| 140 virtual ~TimerTask() { |
| 141 // This task may be getting cleared because the MessageLoop has been |
| 142 // destructed. If so, don't leave the Timer with a dangling pointer |
| 143 // to this now-defunct task. |
| 144 ClearBaseTimer(); |
| 145 } |
| 146 |
138 virtual void Run() { | 147 virtual void Run() { |
139 if (!timer_) // timer_ is null if we were orphaned. | 148 if (!timer_) // timer_ is null if we were orphaned. |
140 return; | 149 return; |
141 SelfType* self = static_cast<SelfType*>(timer_); | 150 if (kIsRepeating) |
142 if (kIsRepeating) { | 151 ResetBaseTimer(); |
143 self->Reset(); | 152 else |
144 } else { | 153 ClearBaseTimer(); |
145 self->delayed_task_ = NULL; | |
146 } | |
147 DispatchToMethod(receiver_, method_, Tuple0()); | 154 DispatchToMethod(receiver_, method_, Tuple0()); |
148 } | 155 } |
| 156 |
149 TimerTask* Clone() const { | 157 TimerTask* Clone() const { |
150 return new TimerTask(delay_, receiver_, method_); | 158 return new TimerTask(delay_, receiver_, method_); |
151 } | 159 } |
| 160 |
152 private: | 161 private: |
| 162 // Inform the Base that the timer is no longer active. |
| 163 void ClearBaseTimer() { |
| 164 if (timer_) { |
| 165 SelfType* self = static_cast<SelfType*>(timer_); |
| 166 // It is possible that the Timer has already been reset, and that this |
| 167 // Task is old. So, if the Timer points to a different task, assume |
| 168 // that the Timer has already taken care of properly setting the task. |
| 169 if (self->delayed_task_ == this) |
| 170 self->delayed_task_ = NULL; |
| 171 } |
| 172 } |
| 173 |
| 174 // Inform the Base that we're resetting the timer. |
| 175 void ResetBaseTimer() { |
| 176 DCHECK(timer_); |
| 177 DCHECK(kIsRepeating); |
| 178 SelfType* self = static_cast<SelfType*>(timer_); |
| 179 self->Reset(); |
| 180 } |
| 181 |
153 Receiver* receiver_; | 182 Receiver* receiver_; |
154 ReceiverMethod method_; | 183 ReceiverMethod method_; |
155 }; | 184 }; |
156 }; | 185 }; |
157 | 186 |
158 //----------------------------------------------------------------------------- | 187 //----------------------------------------------------------------------------- |
159 // A simple, one-shot timer. See usage notes at the top of the file. | 188 // A simple, one-shot timer. See usage notes at the top of the file. |
160 template <class Receiver> | 189 template <class Receiver> |
161 class OneShotTimer : public BaseTimer<Receiver, false> {}; | 190 class OneShotTimer : public BaseTimer<Receiver, false> {}; |
162 | 191 |
163 //----------------------------------------------------------------------------- | 192 //----------------------------------------------------------------------------- |
164 // A simple, repeating timer. See usage notes at the top of the file. | 193 // A simple, repeating timer. See usage notes at the top of the file. |
165 template <class Receiver> | 194 template <class Receiver> |
166 class RepeatingTimer : public BaseTimer<Receiver, true> {}; | 195 class RepeatingTimer : public BaseTimer<Receiver, true> {}; |
167 | 196 |
168 } // namespace base | 197 } // namespace base |
169 | 198 |
170 #endif // BASE_TIMER_H_ | 199 #endif // BASE_TIMER_H_ |
OLD | NEW |