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

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

Issue 1532773002: Revert of Use SequenceChecker to allow Timer to run in SequencedWorkerPool (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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 | « base/timer/timer.h ('k') | base/timer/timer_unittest.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 #include "base/timer/timer.h" 5 #include "base/timer/timer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "base/sequenced_task_runner.h" 11 #include "base/single_thread_task_runner.h"
12 #include "base/threading/sequenced_task_runner_handle.h" 12 #include "base/thread_task_runner_handle.h"
13 #include "base/threading/platform_thread.h"
13 14
14 namespace base { 15 namespace base {
15 16
16 // BaseTimerTaskInternal is a simple delegate for scheduling a callback to 17 // BaseTimerTaskInternal is a simple delegate for scheduling a callback to
17 // Timer in the task runner. It also handles the following edge cases: 18 // Timer in the thread's default task runner. It also handles the following
19 // edge cases:
18 // - deleted by the task runner. 20 // - deleted by the task runner.
19 // - abandoned (orphaned) by Timer. 21 // - abandoned (orphaned) by Timer.
20 class BaseTimerTaskInternal { 22 class BaseTimerTaskInternal {
21 public: 23 public:
22 explicit BaseTimerTaskInternal(Timer* timer) 24 explicit BaseTimerTaskInternal(Timer* timer)
23 : timer_(timer) { 25 : timer_(timer) {
24 } 26 }
25 27
26 ~BaseTimerTaskInternal() { 28 ~BaseTimerTaskInternal() {
27 // This task may be getting cleared because the task runner has been 29 // This task may be getting cleared because the task runner has been
(...skipping 24 matching lines...) Expand all
52 void Abandon() { 54 void Abandon() {
53 timer_ = NULL; 55 timer_ = NULL;
54 } 56 }
55 57
56 private: 58 private:
57 Timer* timer_; 59 Timer* timer_;
58 }; 60 };
59 61
60 Timer::Timer(bool retain_user_task, bool is_repeating) 62 Timer::Timer(bool retain_user_task, bool is_repeating)
61 : scheduled_task_(NULL), 63 : scheduled_task_(NULL),
62 was_scheduled_(false), 64 thread_id_(0),
63 is_repeating_(is_repeating), 65 is_repeating_(is_repeating),
64 retain_user_task_(retain_user_task), 66 retain_user_task_(retain_user_task),
65 is_running_(false) { 67 is_running_(false) {
66 // It is safe for the timer to be created on a different thread/sequence
67 // than the one from which the timer APIs are called. The first call to the
68 // checker's CalledOnValidSequencedThread() method will re-bind the checker,
69 // and later calls will verify that the same task runner is used.
70 origin_sequence_checker_.DetachFromSequence();
71 } 68 }
72 69
73 Timer::Timer(const tracked_objects::Location& posted_from, 70 Timer::Timer(const tracked_objects::Location& posted_from,
74 TimeDelta delay, 71 TimeDelta delay,
75 const base::Closure& user_task, 72 const base::Closure& user_task,
76 bool is_repeating) 73 bool is_repeating)
77 : scheduled_task_(NULL), 74 : scheduled_task_(NULL),
78 posted_from_(posted_from), 75 posted_from_(posted_from),
79 delay_(delay), 76 delay_(delay),
80 user_task_(user_task), 77 user_task_(user_task),
81 was_scheduled_(false), 78 thread_id_(0),
82 is_repeating_(is_repeating), 79 is_repeating_(is_repeating),
83 retain_user_task_(true), 80 retain_user_task_(true),
84 is_running_(false) { 81 is_running_(false) {
85 // See comment in other constructor.
86 origin_sequence_checker_.DetachFromSequence();
87 } 82 }
88 83
89 Timer::~Timer() { 84 Timer::~Timer() {
90 DCHECK(origin_sequence_checker_.CalledOnValidSequencedThread());
91 StopAndAbandon(); 85 StopAndAbandon();
92 } 86 }
93 87
94 bool Timer::IsRunning() const { 88 bool Timer::IsRunning() const {
95 return is_running_; 89 return is_running_;
96 } 90 }
97 91
98 TimeDelta Timer::GetCurrentDelay() const { 92 TimeDelta Timer::GetCurrentDelay() const {
99 return delay_; 93 return delay_;
100 } 94 }
101 95
102 void Timer::SetTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner) { 96 void Timer::SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner) {
103 // Do not allow changing the task runner once something has been scheduled. 97 // Do not allow changing the task runner once something has been scheduled.
104 DCHECK(!was_scheduled_); 98 DCHECK_EQ(thread_id_, 0);
105 destination_task_runner_ = std::move(task_runner); 99 task_runner_.swap(task_runner);
106 } 100 }
107 101
108 void Timer::Start(const tracked_objects::Location& posted_from, 102 void Timer::Start(const tracked_objects::Location& posted_from,
109 TimeDelta delay, 103 TimeDelta delay,
110 const base::Closure& user_task) { 104 const base::Closure& user_task) {
111 SetTaskInfo(posted_from, delay, user_task); 105 SetTaskInfo(posted_from, delay, user_task);
112 Reset(); 106 Reset();
113 } 107 }
114 108
115 void Timer::Stop() { 109 void Timer::Stop() {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 void Timer::SetTaskInfo(const tracked_objects::Location& posted_from, 142 void Timer::SetTaskInfo(const tracked_objects::Location& posted_from,
149 TimeDelta delay, 143 TimeDelta delay,
150 const base::Closure& user_task) { 144 const base::Closure& user_task) {
151 posted_from_ = posted_from; 145 posted_from_ = posted_from;
152 delay_ = delay; 146 delay_ = delay;
153 user_task_ = user_task; 147 user_task_ = user_task;
154 } 148 }
155 149
156 void Timer::PostNewScheduledTask(TimeDelta delay) { 150 void Timer::PostNewScheduledTask(TimeDelta delay) {
157 DCHECK(scheduled_task_ == NULL); 151 DCHECK(scheduled_task_ == NULL);
158 DCHECK(origin_sequence_checker_.CalledOnValidSequencedThread());
159 was_scheduled_ = true;
160 is_running_ = true; 152 is_running_ = true;
161 scheduled_task_ = new BaseTimerTaskInternal(this); 153 scheduled_task_ = new BaseTimerTaskInternal(this);
162 if (delay > TimeDelta::FromMicroseconds(0)) { 154 if (delay > TimeDelta::FromMicroseconds(0)) {
163 GetTaskRunner()->PostDelayedTask(posted_from_, 155 GetTaskRunner()->PostDelayedTask(posted_from_,
164 base::Bind(&BaseTimerTaskInternal::Run, base::Owned(scheduled_task_)), 156 base::Bind(&BaseTimerTaskInternal::Run, base::Owned(scheduled_task_)),
165 delay); 157 delay);
166 scheduled_run_time_ = desired_run_time_ = TimeTicks::Now() + delay; 158 scheduled_run_time_ = desired_run_time_ = TimeTicks::Now() + delay;
167 } else { 159 } else {
168 GetTaskRunner()->PostTask(posted_from_, 160 GetTaskRunner()->PostTask(posted_from_,
169 base::Bind(&BaseTimerTaskInternal::Run, base::Owned(scheduled_task_))); 161 base::Bind(&BaseTimerTaskInternal::Run, base::Owned(scheduled_task_)));
170 scheduled_run_time_ = desired_run_time_ = TimeTicks(); 162 scheduled_run_time_ = desired_run_time_ = TimeTicks();
171 } 163 }
164 // Remember the thread ID that posts the first task -- this will be verified
165 // later when the task is abandoned to detect misuse from multiple threads.
166 if (!thread_id_) {
167 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
168 thread_id_ = static_cast<int>(PlatformThread::CurrentId());
169 }
172 } 170 }
173 171
174 scoped_refptr<SequencedTaskRunner> Timer::GetTaskRunner() { 172 scoped_refptr<SingleThreadTaskRunner> Timer::GetTaskRunner() {
175 return destination_task_runner_.get() ? destination_task_runner_ 173 return task_runner_.get() ? task_runner_ : ThreadTaskRunnerHandle::Get();
176 : SequencedTaskRunnerHandle::Get();
177 } 174 }
178 175
179 void Timer::AbandonScheduledTask() { 176 void Timer::AbandonScheduledTask() {
180 DCHECK(origin_sequence_checker_.CalledOnValidSequencedThread()); 177 DCHECK(thread_id_ == 0 ||
178 thread_id_ == static_cast<int>(PlatformThread::CurrentId()));
181 if (scheduled_task_) { 179 if (scheduled_task_) {
182 scheduled_task_->Abandon(); 180 scheduled_task_->Abandon();
183 scheduled_task_ = NULL; 181 scheduled_task_ = NULL;
184 } 182 }
185 } 183 }
186 184
187 void Timer::RunScheduledTask() { 185 void Timer::RunScheduledTask() {
188 // Task may have been disabled. 186 // Task may have been disabled.
189 if (!is_running_) 187 if (!is_running_)
190 return; 188 return;
(...skipping 20 matching lines...) Expand all
211 PostNewScheduledTask(delay_); 209 PostNewScheduledTask(delay_);
212 else 210 else
213 Stop(); 211 Stop();
214 212
215 task.Run(); 213 task.Run();
216 214
217 // No more member accesses here: *this could be deleted at this point. 215 // No more member accesses here: *this could be deleted at this point.
218 } 216 }
219 217
220 } // namespace base 218 } // namespace base
OLDNEW
« no previous file with comments | « base/timer/timer.h ('k') | base/timer/timer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698