| 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 |