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

Side by Side Diff: components/timers/alarm_timer_chromeos.cc

Issue 1144153004: components: Remove use of MessageLoopProxy and deprecated MessageLoop APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased. Created 5 years, 6 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/timers/alarm_timer_chromeos.h" 5 #include "components/timers/alarm_timer_chromeos.h"
6 6
7 #include <sys/timerfd.h> 7 #include <sys/timerfd.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/lazy_instance.h" 12 #include "base/lazy_instance.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/message_loop/message_loop_proxy.h"
17 #include "base/pending_task.h" 16 #include "base/pending_task.h"
17 #include "base/thread_task_runner_handle.h"
18 #include "base/threading/thread.h" 18 #include "base/threading/thread.h"
19 19
20 namespace timers { 20 namespace timers {
21 namespace { 21 namespace {
22 // This class represents the IO thread that the AlarmTimer::Delegate may use for 22 // This class represents the IO thread that the AlarmTimer::Delegate may use for
23 // watching file descriptors if it gets called from a thread that does not have 23 // watching file descriptors if it gets called from a thread that does not have
24 // a MessageLoopForIO. It is a lazy global instance because it may not always 24 // a MessageLoopForIO. It is a lazy global instance because it may not always
25 // be necessary. 25 // be necessary.
26 class RtcAlarmIOThread : public base::Thread { 26 class RtcAlarmIOThread : public base::Thread {
27 public: 27 public:
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 101
102 // Resets the timer to fire after |delay| has passed. Cancels any 102 // Resets the timer to fire after |delay| has passed. Cancels any
103 // pre-existing delay. 103 // pre-existing delay.
104 void Reset(base::TimeDelta delay); 104 void Reset(base::TimeDelta delay);
105 105
106 // Stops the currently running timer. It should be safe to call this even if 106 // Stops the currently running timer. It should be safe to call this even if
107 // the timer is not running. 107 // the timer is not running.
108 void Stop(); 108 void Stop();
109 109
110 // Sets a hook that will be called when the timer fires and a task has been 110 // Sets a hook that will be called when the timer fires and a task has been
111 // queued on |origin_message_loop_|. Used by tests to wait until a task is 111 // queued on |origin_task_runner_|. Used by tests to wait until a task is
112 // pending in the MessageLoop. 112 // pending in the MessageLoop.
113 void SetTimerFiredCallbackForTest(base::Closure test_callback); 113 void SetTimerFiredCallbackForTest(base::Closure test_callback);
114 114
115 // base::MessageLoopForIO::Watcher overrides. 115 // base::MessageLoopForIO::Watcher overrides.
116 void OnFileCanReadWithoutBlocking(int fd) override; 116 void OnFileCanReadWithoutBlocking(int fd) override;
117 void OnFileCanWriteWithoutBlocking(int fd) override; 117 void OnFileCanWriteWithoutBlocking(int fd) override;
118 118
119 private: 119 private:
120 friend class base::RefCountedThreadSafe<Delegate>; 120 friend class base::RefCountedThreadSafe<Delegate>;
121 ~Delegate() override; 121 ~Delegate() override;
122 122
123 // Actually performs the system calls to set up the timer. This must be 123 // Actually performs the system calls to set up the timer. This must be
124 // called on a MessageLoopForIO. 124 // called on a MessageLoopForIO.
125 void ResetImpl(base::TimeDelta delay, int reset_sequence_number); 125 void ResetImpl(base::TimeDelta delay, int reset_sequence_number);
126 126
127 // Callback that is run when the timer fires. Must be run on 127 // Callback that is run when the timer fires. Must be run on
128 // |origin_message_loop_|. 128 // |origin_task_runner_|.
129 void OnTimerFired(int reset_sequence_number); 129 void OnTimerFired(int reset_sequence_number);
130 130
131 // File descriptor associated with the alarm timer. 131 // File descriptor associated with the alarm timer.
132 int alarm_fd_; 132 int alarm_fd_;
133 133
134 // Message loop which initially started the timer. 134 // Task runner which initially started the timer.
135 scoped_refptr<base::MessageLoopProxy> origin_message_loop_; 135 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
136 136
137 // Callback that should be run when the timer fires. 137 // Callback that should be run when the timer fires.
138 base::Closure on_timer_fired_callback_; 138 base::Closure on_timer_fired_callback_;
139 139
140 // Hook used by tests to be notified when the timer has fired and a task has 140 // Hook used by tests to be notified when the timer has fired and a task has
141 // been queued in the MessageLoop. 141 // been queued in the MessageLoop.
142 base::Closure on_timer_fired_callback_for_test_; 142 base::Closure on_timer_fired_callback_for_test_;
143 143
144 // Manages watching file descriptors. 144 // Manages watching file descriptors.
145 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> fd_watcher_; 145 scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> fd_watcher_;
146 146
147 // The sequence numbers of the last Reset() call handled respectively on 147 // The sequence numbers of the last Reset() call handled respectively on
148 // |origin_message_loop_| and on the MessageLoopForIO used for watching the 148 // |origin_task_runner_| and on the MessageLoopForIO used for watching the
149 // timer file descriptor. Note that these can be the same MessageLoop. 149 // timer file descriptor. Note that these can be the same MessageLoop.
150 // OnTimerFired() runs |on_timer_fired_callback_| only if the sequence number 150 // OnTimerFired() runs |on_timer_fired_callback_| only if the sequence number
151 // it receives from the MessageLoopForIO matches 151 // it receives from the MessageLoopForIO matches
152 // |origin_reset_sequence_number_|. 152 // |origin_reset_sequence_number_|.
153 int origin_reset_sequence_number_; 153 int origin_reset_sequence_number_;
154 int io_reset_sequence_number_; 154 int io_reset_sequence_number_;
155 155
156 DISALLOW_COPY_AND_ASSIGN(Delegate); 156 DISALLOW_COPY_AND_ASSIGN(Delegate);
157 }; 157 };
158 158
(...skipping 11 matching lines...) Expand all
170 AlarmTimer::Delegate::~Delegate() { 170 AlarmTimer::Delegate::~Delegate() {
171 if (alarm_fd_ != -1) 171 if (alarm_fd_ != -1)
172 close(alarm_fd_); 172 close(alarm_fd_);
173 } 173 }
174 174
175 bool AlarmTimer::Delegate::CanWakeFromSuspend() { 175 bool AlarmTimer::Delegate::CanWakeFromSuspend() {
176 return alarm_fd_ != -1; 176 return alarm_fd_ != -1;
177 } 177 }
178 178
179 void AlarmTimer::Delegate::Reset(base::TimeDelta delay) { 179 void AlarmTimer::Delegate::Reset(base::TimeDelta delay) {
180 // Get a proxy for the current message loop. When the timer fires, we will 180 // Get a task runner for the current message loop. When the timer fires, we
181 // will
181 // post tasks to this proxy to let the parent timer know. 182 // post tasks to this proxy to let the parent timer know.
182 origin_message_loop_ = base::MessageLoopProxy::current(); 183 origin_task_runner_ = base::ThreadTaskRunnerHandle::Get();
183 184
184 // Increment the sequence number. Used to invalidate any events that have 185 // Increment the sequence number. Used to invalidate any events that have
185 // been queued but not yet run since the last time Reset() was called. 186 // been queued but not yet run since the last time Reset() was called.
186 origin_reset_sequence_number_++; 187 origin_reset_sequence_number_++;
187 188
188 // Calling timerfd_settime with a zero delay actually clears the timer so if 189 // Calling timerfd_settime with a zero delay actually clears the timer so if
189 // the user has requested a zero delay timer, we need to handle it 190 // the user has requested a zero delay timer, we need to handle it
190 // differently. We queue the task here but we still go ahead and call 191 // differently. We queue the task here but we still go ahead and call
191 // timerfd_settime with the zero delay anyway to cancel any previous delay 192 // timerfd_settime with the zero delay anyway to cancel any previous delay
192 // that might have been programmed. 193 // that might have been programmed.
193 if (delay <= base::TimeDelta::FromMicroseconds(0)) { 194 if (delay <= base::TimeDelta::FromMicroseconds(0)) {
194 // The timerfd_settime documentation is vague on what happens when it is 195 // The timerfd_settime documentation is vague on what happens when it is
195 // passed a negative delay. We can sidestep the issue by ensuring that 196 // passed a negative delay. We can sidestep the issue by ensuring that
196 // the delay is 0. 197 // the delay is 0.
197 delay = base::TimeDelta::FromMicroseconds(0); 198 delay = base::TimeDelta::FromMicroseconds(0);
198 origin_message_loop_->PostTask( 199 origin_task_runner_->PostTask(
199 FROM_HERE, 200 FROM_HERE,
200 base::Bind(&Delegate::OnTimerFired, scoped_refptr<Delegate>(this), 201 base::Bind(&Delegate::OnTimerFired, scoped_refptr<Delegate>(this),
201 origin_reset_sequence_number_)); 202 origin_reset_sequence_number_));
202 } 203 }
203 204
204 // Run ResetImpl() on a MessageLoopForIO. 205 // Run ResetImpl() on a MessageLoopForIO.
205 if (base::MessageLoopForIO::IsCurrent()) { 206 if (base::MessageLoopForIO::IsCurrent()) {
206 ResetImpl(delay, origin_reset_sequence_number_); 207 ResetImpl(delay, origin_reset_sequence_number_);
207 } else { 208 } else {
208 g_io_thread.Pointer()->task_runner()->PostTask( 209 g_io_thread.Pointer()->task_runner()->PostTask(
(...skipping 23 matching lines...) Expand all
232 233
233 void AlarmTimer::Delegate::OnFileCanReadWithoutBlocking(int fd) { 234 void AlarmTimer::Delegate::OnFileCanReadWithoutBlocking(int fd) {
234 DCHECK_EQ(alarm_fd_, fd); 235 DCHECK_EQ(alarm_fd_, fd);
235 236
236 // Read from the fd to ack the event. 237 // Read from the fd to ack the event.
237 char val[sizeof(uint64_t)]; 238 char val[sizeof(uint64_t)];
238 if (!base::ReadFromFD(alarm_fd_, val, sizeof(uint64_t))) 239 if (!base::ReadFromFD(alarm_fd_, val, sizeof(uint64_t)))
239 PLOG(DFATAL) << "Unable to read from timer file descriptor."; 240 PLOG(DFATAL) << "Unable to read from timer file descriptor.";
240 241
241 // Make sure that the parent timer is informed on the proper message loop. 242 // Make sure that the parent timer is informed on the proper message loop.
242 if (origin_message_loop_->RunsTasksOnCurrentThread()) { 243 if (origin_task_runner_->RunsTasksOnCurrentThread()) {
243 OnTimerFired(io_reset_sequence_number_); 244 OnTimerFired(io_reset_sequence_number_);
244 } else { 245 } else {
245 origin_message_loop_->PostTask( 246 origin_task_runner_->PostTask(
246 FROM_HERE, 247 FROM_HERE,
247 base::Bind(&Delegate::OnTimerFired, scoped_refptr<Delegate>(this), 248 base::Bind(&Delegate::OnTimerFired, scoped_refptr<Delegate>(this),
248 io_reset_sequence_number_)); 249 io_reset_sequence_number_));
249 } 250 }
250 } 251 }
251 252
252 void AlarmTimer::Delegate::OnFileCanWriteWithoutBlocking(int fd) { 253 void AlarmTimer::Delegate::OnFileCanWriteWithoutBlocking(int fd) {
253 NOTREACHED(); 254 NOTREACHED();
254 } 255 }
255 256
(...skipping 28 matching lines...) Expand all
284 itimerspec alarm_time = {}; 285 itimerspec alarm_time = {};
285 alarm_time.it_value.tv_sec = delay.InSeconds(); 286 alarm_time.it_value.tv_sec = delay.InSeconds();
286 alarm_time.it_value.tv_nsec = 287 alarm_time.it_value.tv_nsec =
287 (delay.InMicroseconds() % base::Time::kMicrosecondsPerSecond) * 288 (delay.InMicroseconds() % base::Time::kMicrosecondsPerSecond) *
288 base::Time::kNanosecondsPerMicrosecond; 289 base::Time::kNanosecondsPerMicrosecond;
289 if (timerfd_settime(alarm_fd_, 0, &alarm_time, NULL) < 0) 290 if (timerfd_settime(alarm_fd_, 0, &alarm_time, NULL) < 0)
290 PLOG(ERROR) << "Error while setting alarm time. Timer will not fire"; 291 PLOG(ERROR) << "Error while setting alarm time. Timer will not fire";
291 } 292 }
292 293
293 void AlarmTimer::Delegate::OnTimerFired(int reset_sequence_number) { 294 void AlarmTimer::Delegate::OnTimerFired(int reset_sequence_number) {
294 DCHECK(origin_message_loop_->RunsTasksOnCurrentThread()); 295 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread());
295 296
296 // If a test wants to be notified when this function is about to run, then 297 // If a test wants to be notified when this function is about to run, then
297 // re-queue this task in the MessageLoop and run the test's callback. 298 // re-queue this task in the MessageLoop and run the test's callback.
298 if (!on_timer_fired_callback_for_test_.is_null()) { 299 if (!on_timer_fired_callback_for_test_.is_null()) {
299 origin_message_loop_->PostTask( 300 origin_task_runner_->PostTask(
300 FROM_HERE, 301 FROM_HERE,
301 base::Bind(&Delegate::OnTimerFired, scoped_refptr<Delegate>(this), 302 base::Bind(&Delegate::OnTimerFired, scoped_refptr<Delegate>(this),
302 reset_sequence_number)); 303 reset_sequence_number));
303 304
304 on_timer_fired_callback_for_test_.Run(); 305 on_timer_fired_callback_for_test_.Run();
305 on_timer_fired_callback_for_test_.Reset(); 306 on_timer_fired_callback_for_test_.Reset();
306 return; 307 return;
307 } 308 }
308 309
309 // Check to make sure that the timer was not reset in the time between when 310 // Check to make sure that the timer was not reset in the time between when
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 SimpleAlarmTimer::SimpleAlarmTimer(const tracked_objects::Location& posted_from, 458 SimpleAlarmTimer::SimpleAlarmTimer(const tracked_objects::Location& posted_from,
458 base::TimeDelta delay, 459 base::TimeDelta delay,
459 const base::Closure& user_task) 460 const base::Closure& user_task)
460 : AlarmTimer(posted_from, delay, user_task, false) { 461 : AlarmTimer(posted_from, delay, user_task, false) {
461 } 462 }
462 463
463 SimpleAlarmTimer::~SimpleAlarmTimer() { 464 SimpleAlarmTimer::~SimpleAlarmTimer() {
464 } 465 }
465 466
466 } // namespace timers 467 } // namespace timers
OLDNEW
« no previous file with comments | « components/sync_driver/ui_data_type_controller_unittest.cc ('k') | components/tracing/child_trace_message_filter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698