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

Side by Side Diff: base/timer.cc

Issue 10213012: Use MessageLoopProxy instead of MessageLoop in base::Timer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 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 | « no previous file | no next file » | 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 #include "base/timer.h" 5 #include "base/timer.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/message_loop.h" 8 #include "base/single_thread_task_runner.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "base/threading/platform_thread.h"
9 11
10 namespace base { 12 namespace base {
11 13
12 // BaseTimerTaskInternal is a simple delegate for scheduling a callback to 14 // BaseTimerTaskInternal is a simple delegate for scheduling a callback to
13 // Timer in the MessageLoop. It also handles the following edge 15 // Timer in the thread's default task runner. It also handles the following
14 // cases: 16 // edge cases:
15 // - deleted by MessageLoop. 17 // - deleted by the task runner.
16 // - abandoned (orphaned) by Timer. 18 // - abandoned (orphaned) by Timer.
17 class BaseTimerTaskInternal { 19 class BaseTimerTaskInternal {
18 public: 20 public:
19 BaseTimerTaskInternal(Timer* timer) 21 BaseTimerTaskInternal(Timer* timer)
20 : timer_(timer) { 22 : timer_(timer) {
21 } 23 }
22 24
23 ~BaseTimerTaskInternal() { 25 ~BaseTimerTaskInternal() {
24 // This task may be getting cleared because the MessageLoop has been 26 // This task may be getting cleared because the task runner has been
25 // destructed. If so, don't leave Timer with a dangling pointer 27 // destructed. If so, don't leave Timer with a dangling pointer
26 // to this. 28 // to this.
27 if (timer_) 29 if (timer_)
28 timer_->StopAndAbandon(); 30 timer_->StopAndAbandon();
29 } 31 }
30 32
31 void Run() { 33 void Run() {
32 // timer_ is NULL if we were abandoned. 34 // timer_ is NULL if we were abandoned.
33 if (!timer_) 35 if (!timer_)
34 return; 36 return;
35 37
36 // *this will be deleted by the MessageLoop, so Timer needs to 38 // *this will be deleted by the task runner, so Timer needs to
37 // forget us: 39 // forget us:
38 timer_->scheduled_task_ = NULL; 40 timer_->scheduled_task_ = NULL;
39 41
40 // Although Timer should not call back into *this, let's clear 42 // Although Timer should not call back into *this, let's clear
41 // the timer_ member first to be pedantic. 43 // the timer_ member first to be pedantic.
42 Timer* timer = timer_; 44 Timer* timer = timer_;
43 timer_ = NULL; 45 timer_ = NULL;
44 timer->RunScheduledTask(); 46 timer->RunScheduledTask();
45 } 47 }
46 48
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 const base::Closure& user_task) { 124 const base::Closure& user_task) {
123 posted_from_ = posted_from; 125 posted_from_ = posted_from;
124 delay_ = delay; 126 delay_ = delay;
125 user_task_ = user_task; 127 user_task_ = user_task;
126 } 128 }
127 129
128 void Timer::PostNewScheduledTask(TimeDelta delay) { 130 void Timer::PostNewScheduledTask(TimeDelta delay) {
129 DCHECK(scheduled_task_ == NULL); 131 DCHECK(scheduled_task_ == NULL);
130 is_running_ = true; 132 is_running_ = true;
131 scheduled_task_ = new BaseTimerTaskInternal(this); 133 scheduled_task_ = new BaseTimerTaskInternal(this);
132 MessageLoop::current()->PostDelayedTask(posted_from_, 134 ThreadTaskRunnerHandle::Get()->PostDelayedTask(posted_from_,
133 base::Bind(&BaseTimerTaskInternal::Run, base::Owned(scheduled_task_)), 135 base::Bind(&BaseTimerTaskInternal::Run, base::Owned(scheduled_task_)),
134 delay); 136 delay);
135 scheduled_run_time_ = desired_run_time_ = TimeTicks::Now() + delay; 137 scheduled_run_time_ = desired_run_time_ = TimeTicks::Now() + delay;
136 // Remember the thread ID that posts the first task -- this will be verified 138 // Remember the thread ID that posts the first task -- this will be verified
137 // later when the task is abandoned to detect misuse from multiple threads. 139 // later when the task is abandoned to detect misuse from multiple threads.
138 if (!thread_id_) 140 if (!thread_id_)
139 thread_id_ = static_cast<int>(PlatformThread::CurrentId()); 141 thread_id_ = static_cast<int>(PlatformThread::CurrentId());
140 } 142 }
141 143
142 void Timer::AbandonScheduledTask() { 144 void Timer::AbandonScheduledTask() {
143 DCHECK(thread_id_ == 0 || 145 DCHECK(thread_id_ == 0 ||
144 thread_id_ == static_cast<int>(PlatformThread::CurrentId())); 146 thread_id_ == static_cast<int>(PlatformThread::CurrentId()));
145 if (scheduled_task_) { 147 if (scheduled_task_) {
146 scheduled_task_->Abandon(); 148 scheduled_task_->Abandon();
147 scheduled_task_ = NULL; 149 scheduled_task_ = NULL;
148 } 150 }
149 } 151 }
150 152
151 void Timer::RunScheduledTask() { 153 void Timer::RunScheduledTask() {
152 // Task may have been disabled. 154 // Task may have been disabled.
153 if (!is_running_) 155 if (!is_running_)
154 return; 156 return;
155 157
156 // First check if we need to delay the task because of a new target time. 158 // First check if we need to delay the task because of a new target time.
157 if (desired_run_time_ > scheduled_run_time_) { 159 if (desired_run_time_ > scheduled_run_time_) {
158 // TimeTicks::Now() can be expensive, so only call it if we know the user 160 // TimeTicks::Now() can be expensive, so only call it if we know the user
159 // has changed the desired_run_time_. 161 // has changed the desired_run_time_.
160 TimeTicks now = TimeTicks::Now(); 162 TimeTicks now = TimeTicks::Now();
161 // MessageLoop may have called us late anyway, so only post a continuation 163 // Task runner may have called us late anyway, so only post a continuation
162 // task if the desired_run_time_ is in the future. 164 // task if the desired_run_time_ is in the future.
163 if (desired_run_time_ > now) { 165 if (desired_run_time_ > now) {
164 // Post a new task to span the remaining time. 166 // Post a new task to span the remaining time.
165 PostNewScheduledTask(desired_run_time_ - now); 167 PostNewScheduledTask(desired_run_time_ - now);
166 return; 168 return;
167 } 169 }
168 } 170 }
169 171
170 // Make a local copy of the task to run. The Stop method will reset the 172 // Make a local copy of the task to run. The Stop method will reset the
171 // user_task_ member if retain_user_task_ is false. 173 // user_task_ member if retain_user_task_ is false.
172 base::Closure task = user_task_; 174 base::Closure task = user_task_;
173 175
174 if (is_repeating_) 176 if (is_repeating_)
175 PostNewScheduledTask(delay_); 177 PostNewScheduledTask(delay_);
176 else 178 else
177 Stop(); 179 Stop();
178 180
179 task.Run(); 181 task.Run();
180 182
181 // No more member accesses here: *this could be deleted at this point. 183 // No more member accesses here: *this could be deleted at this point.
182 } 184 }
183 185
184 } // namespace base 186 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698