| OLD | NEW |
| 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/files/file_path_watcher_kqueue.h" | 5 #include "base/files/file_path_watcher_kqueue.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <sys/param.h> | 9 #include <sys/param.h> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 15 #include "base/threading/sequenced_task_runner_handle.h" | 15 #include "base/threading/sequenced_task_runner_handle.h" |
| 16 | 16 |
| 17 // On some platforms these are not defined. | 17 // On some platforms these are not defined. |
| 18 #if !defined(EV_RECEIPT) | 18 #if !defined(EV_RECEIPT) |
| 19 #define EV_RECEIPT 0 | 19 #define EV_RECEIPT 0 |
| 20 #endif | 20 #endif |
| 21 #if !defined(O_EVTONLY) | 21 #if !defined(O_EVTONLY) |
| 22 #define O_EVTONLY O_RDONLY | 22 #define O_EVTONLY O_RDONLY |
| 23 #endif | 23 #endif |
| 24 | 24 |
| 25 namespace base { | 25 namespace base { |
| 26 | 26 |
| 27 FilePathWatcherKQueue::FilePathWatcherKQueue() : kqueue_(-1) {} | 27 FilePathWatcherKQueue::FilePathWatcherKQueue() : kqueue_(-1) {} |
| 28 | 28 |
| 29 FilePathWatcherKQueue::~FilePathWatcherKQueue() {} | 29 FilePathWatcherKQueue::~FilePathWatcherKQueue() { |
| 30 DCHECK(!task_runner() || task_runner()->RunsTasksOnCurrentThread()); |
| 31 } |
| 30 | 32 |
| 31 void FilePathWatcherKQueue::ReleaseEvent(struct kevent& event) { | 33 void FilePathWatcherKQueue::ReleaseEvent(struct kevent& event) { |
| 32 CloseFileDescriptor(&event.ident); | 34 CloseFileDescriptor(&event.ident); |
| 33 EventData* entry = EventDataForKevent(event); | 35 EventData* entry = EventDataForKevent(event); |
| 34 delete entry; | 36 delete entry; |
| 35 event.udata = NULL; | 37 event.udata = NULL; |
| 36 } | 38 } |
| 37 | 39 |
| 38 int FilePathWatcherKQueue::EventsForPath(FilePath path, EventVector* events) { | 40 int FilePathWatcherKQueue::EventsForPath(FilePath path, EventVector* events) { |
| 39 // Make sure that we are working with a clean slate. | 41 // Make sure that we are working with a clean slate. |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 &responses[0], last_entry, NULL)); | 260 &responses[0], last_entry, NULL)); |
| 259 if (!AreKeventValuesValid(&responses[0], count)) { | 261 if (!AreKeventValuesValid(&responses[0], count)) { |
| 260 // Calling Cancel() here to close any file descriptors that were opened. | 262 // Calling Cancel() here to close any file descriptors that were opened. |
| 261 // This would happen in the destructor anyways, but FilePathWatchers tend to | 263 // This would happen in the destructor anyways, but FilePathWatchers tend to |
| 262 // be long lived, and if an error has occurred, there is no reason to waste | 264 // be long lived, and if an error has occurred, there is no reason to waste |
| 263 // the file descriptors. | 265 // the file descriptors. |
| 264 Cancel(); | 266 Cancel(); |
| 265 return false; | 267 return false; |
| 266 } | 268 } |
| 267 | 269 |
| 268 // This creates an ownership cycle (|this| owns |kqueue_watch_controller_| | 270 // It's safe to use Unretained() because the watch is cancelled and the |
| 269 // which owns a callback which owns |this|). The cycle is broken when | 271 // callback cannot be invoked after |kqueue_watch_controller_| (which is a |
| 270 // |kqueue_watch_controller_| is reset in Cancel(). | 272 // member of |this|) has been deleted. |
| 271 kqueue_watch_controller_ = FileDescriptorWatcher::WatchReadable( | 273 kqueue_watch_controller_ = FileDescriptorWatcher::WatchReadable( |
| 272 kqueue_, Bind(&FilePathWatcherKQueue::OnKQueueReadable, this)); | 274 kqueue_, |
| 275 Bind(&FilePathWatcherKQueue::OnKQueueReadable, Unretained(this))); |
| 276 |
| 273 return true; | 277 return true; |
| 274 } | 278 } |
| 275 | 279 |
| 276 void FilePathWatcherKQueue::Cancel() { | 280 void FilePathWatcherKQueue::Cancel() { |
| 277 if (!task_runner()) { | 281 if (!task_runner()) { |
| 278 set_cancelled(); | 282 set_cancelled(); |
| 279 return; | 283 return; |
| 280 } | 284 } |
| 281 | 285 |
| 282 DCHECK(task_runner()->RunsTasksOnCurrentThread()); | 286 DCHECK(task_runner()->RunsTasksOnCurrentThread()); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 Cancel(); | 363 Cancel(); |
| 360 } | 364 } |
| 361 } | 365 } |
| 362 | 366 |
| 363 if (send_notification) { | 367 if (send_notification) { |
| 364 callback_.Run(target_, false); | 368 callback_.Run(target_, false); |
| 365 } | 369 } |
| 366 } | 370 } |
| 367 | 371 |
| 368 } // namespace base | 372 } // namespace base |
| OLD | NEW |