| Index: base/timer.h
|
| ===================================================================
|
| --- base/timer.h (revision 6222)
|
| +++ base/timer.h (working copy)
|
| @@ -82,6 +82,7 @@
|
| TimerTask(TimeDelta delay) : delay_(delay) {
|
| // timer_ is set in InitiateDelayedTask.
|
| }
|
| + virtual ~TimerTask() {}
|
| BaseTimer_Helper* timer_;
|
| TimeDelta delay_;
|
| };
|
| @@ -135,21 +136,49 @@
|
| receiver_(receiver),
|
| method_(method) {
|
| }
|
| +
|
| + virtual ~TimerTask() {
|
| + // This task may be getting cleared because the MessageLoop has been
|
| + // destructed. If so, don't leave the Timer with a dangling pointer
|
| + // to this now-defunct task.
|
| + ClearBaseTimer();
|
| + }
|
| +
|
| virtual void Run() {
|
| if (!timer_) // timer_ is null if we were orphaned.
|
| return;
|
| - SelfType* self = static_cast<SelfType*>(timer_);
|
| - if (kIsRepeating) {
|
| - self->Reset();
|
| - } else {
|
| - self->delayed_task_ = NULL;
|
| - }
|
| + if (kIsRepeating)
|
| + ResetBaseTimer();
|
| + else
|
| + ClearBaseTimer();
|
| DispatchToMethod(receiver_, method_, Tuple0());
|
| }
|
| +
|
| TimerTask* Clone() const {
|
| return new TimerTask(delay_, receiver_, method_);
|
| }
|
| +
|
| private:
|
| + // Inform the Base that the timer is no longer active.
|
| + void ClearBaseTimer() {
|
| + if (timer_) {
|
| + SelfType* self = static_cast<SelfType*>(timer_);
|
| + // It is possible that the Timer has already been reset, and that this
|
| + // Task is old. So, if the Timer points to a different task, assume
|
| + // that the Timer has already taken care of properly setting the task.
|
| + if (self->delayed_task_ == this)
|
| + self->delayed_task_ = NULL;
|
| + }
|
| + }
|
| +
|
| + // Inform the Base that we're resetting the timer.
|
| + void ResetBaseTimer() {
|
| + DCHECK(timer_);
|
| + DCHECK(kIsRepeating);
|
| + SelfType* self = static_cast<SelfType*>(timer_);
|
| + self->Reset();
|
| + }
|
| +
|
| Receiver* receiver_;
|
| ReceiverMethod method_;
|
| };
|
|
|