OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/files/file_descriptor_watcher_posix.h" | 5 #include "base/files/file_descriptor_watcher_posix.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/lazy_instance.h" | |
9 #include "base/logging.h" | 8 #include "base/logging.h" |
10 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
11 #include "base/sequenced_task_runner.h" | 10 #include "base/sequenced_task_runner.h" |
12 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
13 #include "base/threading/sequenced_task_runner_handle.h" | 12 #include "base/threading/sequenced_task_runner_handle.h" |
14 #include "base/threading/thread_checker.h" | 13 #include "base/threading/thread_checker.h" |
15 #include "base/threading/thread_local.h" | 14 #include "base/threading/thread_local.h" |
16 | 15 |
17 namespace base { | 16 namespace base { |
18 | 17 |
19 namespace { | 18 namespace { |
20 | 19 |
21 // MessageLoopForIO used to watch file descriptors for which callbacks are | 20 // MessageLoopForIO used to watch file descriptors for which callbacks are |
22 // registered from a given thread. | 21 // registered from a given thread. |
23 LazyInstance<ThreadLocalPointer<MessageLoopForIO>>::Leaky | 22 ThreadLocalPointer<MessageLoopForIO>* GetTLSMessageLoopForIO() { |
24 tls_message_loop_for_io = LAZY_INSTANCE_INITIALIZER; | 23 static auto tls_message_loop_for_io = |
| 24 new ThreadLocalPointer<MessageLoopForIO>(); |
| 25 return tls_message_loop_for_io; |
| 26 } |
25 | 27 |
26 } // namespace | 28 } // namespace |
27 | 29 |
28 FileDescriptorWatcher::Controller::~Controller() { | 30 FileDescriptorWatcher::Controller::~Controller() { |
29 DCHECK(sequence_checker_.CalledOnValidSequence()); | 31 DCHECK(sequence_checker_.CalledOnValidSequence()); |
30 | 32 |
31 // Delete |watcher_| on the MessageLoopForIO. | 33 // Delete |watcher_| on the MessageLoopForIO. |
32 // | 34 // |
33 // If the MessageLoopForIO is deleted before Watcher::StartWatching() runs, | 35 // If the MessageLoopForIO is deleted before Watcher::StartWatching() runs, |
34 // |watcher_| is leaked. If the MessageLoopForIO is deleted after | 36 // |watcher_| is leaked. If the MessageLoopForIO is deleted after |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 // MessageLoopForIO. If the MessageLoopForIO is deleted before the delete task | 147 // MessageLoopForIO. If the MessageLoopForIO is deleted before the delete task |
146 // runs, the following line takes care of deleting the Watcher. | 148 // runs, the following line takes care of deleting the Watcher. |
147 delete this; | 149 delete this; |
148 } | 150 } |
149 | 151 |
150 FileDescriptorWatcher::Controller::Controller(MessageLoopForIO::Mode mode, | 152 FileDescriptorWatcher::Controller::Controller(MessageLoopForIO::Mode mode, |
151 int fd, | 153 int fd, |
152 const Closure& callback) | 154 const Closure& callback) |
153 : callback_(callback), | 155 : callback_(callback), |
154 message_loop_for_io_task_runner_( | 156 message_loop_for_io_task_runner_( |
155 tls_message_loop_for_io.Get().Get()->task_runner()), | 157 GetTLSMessageLoopForIO()->Get()->task_runner()), |
156 weak_factory_(this) { | 158 weak_factory_(this) { |
157 DCHECK(!callback_.is_null()); | 159 DCHECK(!callback_.is_null()); |
158 DCHECK(message_loop_for_io_task_runner_); | 160 DCHECK(message_loop_for_io_task_runner_); |
159 watcher_ = MakeUnique<Watcher>(weak_factory_.GetWeakPtr(), mode, fd); | 161 watcher_ = MakeUnique<Watcher>(weak_factory_.GetWeakPtr(), mode, fd); |
160 StartWatching(); | 162 StartWatching(); |
161 } | 163 } |
162 | 164 |
163 void FileDescriptorWatcher::Controller::StartWatching() { | 165 void FileDescriptorWatcher::Controller::StartWatching() { |
164 DCHECK(sequence_checker_.CalledOnValidSequence()); | 166 DCHECK(sequence_checker_.CalledOnValidSequence()); |
165 // It is safe to use Unretained() below because |watcher_| can only be deleted | 167 // It is safe to use Unretained() below because |watcher_| can only be deleted |
(...skipping 12 matching lines...) Expand all Loading... |
178 callback_.Run(); | 180 callback_.Run(); |
179 | 181 |
180 // If |this| wasn't deleted, re-enable the watch. | 182 // If |this| wasn't deleted, re-enable the watch. |
181 if (weak_this) | 183 if (weak_this) |
182 StartWatching(); | 184 StartWatching(); |
183 } | 185 } |
184 | 186 |
185 FileDescriptorWatcher::FileDescriptorWatcher( | 187 FileDescriptorWatcher::FileDescriptorWatcher( |
186 MessageLoopForIO* message_loop_for_io) { | 188 MessageLoopForIO* message_loop_for_io) { |
187 DCHECK(message_loop_for_io); | 189 DCHECK(message_loop_for_io); |
188 DCHECK(!tls_message_loop_for_io.Get().Get()); | 190 DCHECK(!GetTLSMessageLoopForIO()); |
189 tls_message_loop_for_io.Get().Set(message_loop_for_io); | 191 GetTLSMessageLoopForIO()->Set(message_loop_for_io); |
190 } | 192 } |
191 | 193 |
192 FileDescriptorWatcher::~FileDescriptorWatcher() { | 194 FileDescriptorWatcher::~FileDescriptorWatcher() { |
193 tls_message_loop_for_io.Get().Set(nullptr); | 195 GetTLSMessageLoopForIO()->Set(nullptr); |
194 } | 196 } |
195 | 197 |
196 std::unique_ptr<FileDescriptorWatcher::Controller> | 198 std::unique_ptr<FileDescriptorWatcher::Controller> |
197 FileDescriptorWatcher::WatchReadable(int fd, const Closure& callback) { | 199 FileDescriptorWatcher::WatchReadable(int fd, const Closure& callback) { |
198 return WrapUnique(new Controller(MessageLoopForIO::WATCH_READ, fd, callback)); | 200 return WrapUnique(new Controller(MessageLoopForIO::WATCH_READ, fd, callback)); |
199 } | 201 } |
200 | 202 |
201 std::unique_ptr<FileDescriptorWatcher::Controller> | 203 std::unique_ptr<FileDescriptorWatcher::Controller> |
202 FileDescriptorWatcher::WatchWritable(int fd, const Closure& callback) { | 204 FileDescriptorWatcher::WatchWritable(int fd, const Closure& callback) { |
203 return WrapUnique( | 205 return WrapUnique( |
204 new Controller(MessageLoopForIO::WATCH_WRITE, fd, callback)); | 206 new Controller(MessageLoopForIO::WATCH_WRITE, fd, callback)); |
205 } | 207 } |
206 | 208 |
207 } // namespace base | 209 } // namespace base |
OLD | NEW |