OLD | NEW |
---|---|
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/rtc_alarm.h" | 5 #include "components/timers/rtc_alarm.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/files/file_util.h" | 10 #include "base/files/file_util.h" |
11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/message_loop/message_loop_proxy.h" | 14 #include "base/message_loop/message_loop_proxy.h" |
15 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
16 | 16 |
17 namespace timers { | 17 namespace timers { |
18 | 18 |
19 namespace { | 19 namespace { |
20 // Helper class to ensure that the IO thread we will use for watching file | 20 // Helper class to ensure that the IO thread we will use for watching file |
21 // descriptors is started only once. | 21 // descriptors is started only once. |
22 class IOThreadStartHelper { | 22 class IOThreadStartHelper { |
23 public: | 23 public: |
24 IOThreadStartHelper() : thread_(new base::Thread("RTC Alarm IO Thread")) { | 24 IOThreadStartHelper() : thread_(new base::Thread("RTC Alarm IO Thread")) { |
25 CHECK(thread_->StartWithOptions( | 25 CHECK(thread_->StartWithOptions( |
26 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); | 26 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); |
27 } | 27 } |
28 ~IOThreadStartHelper() {} | 28 ~IOThreadStartHelper() {} |
29 | 29 |
30 base::Thread& operator*() const { return *thread_.get(); } | 30 base::Thread& operator*() const { return *thread_.get(); } |
gromer
2014/12/05 20:13:41
https://engdoc.corp.google.com/eng/doc/devguide/cp
Chirantan Ekbote
2014/12/31 00:58:29
This class exists because I needed a thread-safe w
gromer
2015/02/10 23:47:10
You seem to have implemented exactly the fix I was
| |
31 | 31 |
32 base::Thread* operator->() const { return thread_.get(); } | 32 base::Thread* operator->() const { return thread_.get(); } |
33 | 33 |
34 private: | 34 private: |
35 scoped_ptr<base::Thread> thread_; | 35 scoped_ptr<base::Thread> thread_; |
36 }; | 36 }; |
37 | 37 |
38 base::LazyInstance<IOThreadStartHelper> g_io_thread = LAZY_INSTANCE_INITIALIZER; | 38 base::LazyInstance<IOThreadStartHelper> g_io_thread = LAZY_INSTANCE_INITIALIZER; |
39 | 39 |
40 } // namespace | 40 } // namespace |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 // differently. We queue the task here but we still go ahead and call | 88 // differently. We queue the task here but we still go ahead and call |
89 // timerfd_settime with the zero delay anyway to cancel any previous delay | 89 // timerfd_settime with the zero delay anyway to cancel any previous delay |
90 // that might have been programmed. | 90 // that might have been programmed. |
91 if (delay == base::TimeDelta()) { | 91 if (delay == base::TimeDelta()) { |
92 origin_message_loop_->PostTask(FROM_HERE, | 92 origin_message_loop_->PostTask(FROM_HERE, |
93 base::Bind(&RtcAlarm::OnTimerFired, | 93 base::Bind(&RtcAlarm::OnTimerFired, |
94 scoped_refptr<RtcAlarm>(this), | 94 scoped_refptr<RtcAlarm>(this), |
95 origin_event_id_)); | 95 origin_event_id_)); |
96 } | 96 } |
97 | 97 |
98 // Make sure that we are running on a MessageLoopForIO. | 98 // Make sure that we are running on a MessageLoopForIO. |
gromer
2014/12/05 20:13:41
This seems misleading- "Make sure X" to me implies
Chirantan Ekbote
2014/12/31 00:58:29
Acknowledged.
| |
99 if (!base::MessageLoopForIO::IsCurrent()) { | 99 if (!base::MessageLoopForIO::IsCurrent()) { |
100 g_io_thread.Get()->task_runner()->PostTask( | 100 g_io_thread.Get()->task_runner()->PostTask( |
101 FROM_HERE, | 101 FROM_HERE, |
102 base::Bind(&RtcAlarm::ResetImpl, | 102 base::Bind(&RtcAlarm::ResetImpl, |
103 scoped_refptr<RtcAlarm>(this), | 103 scoped_refptr<RtcAlarm>(this), |
104 delay, | 104 delay, |
105 origin_event_id_)); | 105 origin_event_id_)); |
106 return; | 106 return; |
107 } | 107 } |
108 | 108 |
109 ResetImpl(delay, origin_event_id_); | 109 ResetImpl(delay, origin_event_id_); |
gromer
2014/12/05 20:13:41
If this were inside an else-block, it would be muc
Chirantan Ekbote
2014/12/31 00:58:29
Acknowledged.
| |
110 } | 110 } |
111 | 111 |
112 void RtcAlarm::OnFileCanReadWithoutBlocking(int fd) { | 112 void RtcAlarm::OnFileCanReadWithoutBlocking(int fd) { |
113 DCHECK_EQ(alarm_fd_, fd); | 113 DCHECK_EQ(alarm_fd_, fd); |
114 | 114 |
115 // Read from the fd to ack the event. | 115 // Read from the fd to ack the event. |
116 char val[sizeof(uint64_t)]; | 116 char val[sizeof(uint64_t)]; |
117 base::ReadFromFD(alarm_fd_, val, sizeof(uint64_t)); | 117 base::ReadFromFD(alarm_fd_, val, sizeof(uint64_t)); |
118 | 118 |
119 // Make sure that the parent timer is informed on the proper message loop. | 119 // Make sure that the parent timer is informed on the proper message loop. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 void RtcAlarm::OnTimerFired(int event_id) { | 169 void RtcAlarm::OnTimerFired(int event_id) { |
170 DCHECK(origin_message_loop_->RunsTasksOnCurrentThread()); | 170 DCHECK(origin_message_loop_->RunsTasksOnCurrentThread()); |
171 | 171 |
172 // Check to make sure that the timer was not reset in the time between when | 172 // Check to make sure that the timer was not reset in the time between when |
173 // this task was queued to run and now. If it was reset, then don't do | 173 // this task was queued to run and now. If it was reset, then don't do |
174 // anything. | 174 // anything. |
175 if (event_id != origin_event_id_) | 175 if (event_id != origin_event_id_) |
176 return; | 176 return; |
177 | 177 |
178 if (parent_) | 178 if (parent_) |
179 parent_->OnTimerFired(); | 179 parent_->OnTimerFired(); |
gromer
2014/12/05 20:13:41
Isn't there a race condition where parent_ could b
Chirantan Ekbote
2014/12/31 00:58:29
No. WeakPtrs can only be dereferenced and invalid
| |
180 } | 180 } |
181 | 181 |
182 | |
182 } // namespace timers | 183 } // namespace timers |
OLD | NEW |