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

Side by Side Diff: base/files/file_path_watcher_kqueue.cc

Issue 11876025: Eliminate FilePathWatcher::Delegate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « base/files/file_path_watcher.cc ('k') | base/files/file_path_watcher_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.h" 5 #include "base/files/file_path_watcher.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <sys/event.h> 8 #include <sys/event.h>
9 #include <sys/param.h> 9 #include <sys/param.h>
10 10
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 // MessageLoopForIO::Watcher overrides. 59 // MessageLoopForIO::Watcher overrides.
60 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; 60 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
61 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; 61 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE;
62 62
63 // MessageLoop::DestructionObserver overrides. 63 // MessageLoop::DestructionObserver overrides.
64 virtual void WillDestroyCurrentMessageLoop() OVERRIDE; 64 virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
65 65
66 // FilePathWatcher::PlatformDelegate overrides. 66 // FilePathWatcher::PlatformDelegate overrides.
67 virtual bool Watch(const FilePath& path, 67 virtual bool Watch(const FilePath& path,
68 bool recursive, 68 bool recursive,
69 FilePathWatcher::Delegate* delegate) OVERRIDE; 69 const FilePathWatcher::Callback& callback) OVERRIDE;
70 virtual void Cancel() OVERRIDE; 70 virtual void Cancel() OVERRIDE;
71 71
72 protected: 72 protected:
73 virtual ~FilePathWatcherImpl() {} 73 virtual ~FilePathWatcherImpl() {}
74 74
75 private: 75 private:
76 class EventData { 76 class EventData {
77 public: 77 public:
78 EventData(const FilePath& path, const FilePath::StringType& subdir) 78 EventData(const FilePath& path, const FilePath::StringType& subdir)
79 : path_(path), subdir_(subdir) { } 79 : path_(path), subdir_(subdir) { }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 return event.ident != static_cast<uintptr_t>(-1); 134 return event.ident != static_cast<uintptr_t>(-1);
135 } 135 }
136 136
137 static EventData* EventDataForKevent(const struct kevent& event) { 137 static EventData* EventDataForKevent(const struct kevent& event) {
138 return reinterpret_cast<EventData*>(event.udata); 138 return reinterpret_cast<EventData*>(event.udata);
139 } 139 }
140 140
141 EventVector events_; 141 EventVector events_;
142 scoped_refptr<base::MessageLoopProxy> io_message_loop_; 142 scoped_refptr<base::MessageLoopProxy> io_message_loop_;
143 MessageLoopForIO::FileDescriptorWatcher kqueue_watcher_; 143 MessageLoopForIO::FileDescriptorWatcher kqueue_watcher_;
144 scoped_refptr<FilePathWatcher::Delegate> delegate_; 144 FilePathWatcher::Callback callback_;
145 FilePath target_; 145 FilePath target_;
146 int kqueue_; 146 int kqueue_;
147 147
148 DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl); 148 DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl);
149 }; 149 };
150 150
151 void FilePathWatcherImpl::ReleaseEvent(struct kevent& event) { 151 void FilePathWatcherImpl::ReleaseEvent(struct kevent& event) {
152 CloseFileDescriptor(reinterpret_cast<int*>(&event.ident)); 152 CloseFileDescriptor(reinterpret_cast<int*>(&event.ident));
153 EventData* entry = EventDataForKevent(event); 153 EventData* entry = EventDataForKevent(event);
154 delete entry; 154 delete entry;
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // them in |updates|. |count| will contain the number of updates that have 357 // them in |updates|. |count| will contain the number of updates that have
358 // occurred. 358 // occurred.
359 EventVector updates(events_.size()); 359 EventVector updates(events_.size());
360 struct timespec timeout = {0, 0}; 360 struct timespec timeout = {0, 0};
361 int count = HANDLE_EINTR(kevent(kqueue_, NULL, 0, &updates[0], updates.size(), 361 int count = HANDLE_EINTR(kevent(kqueue_, NULL, 0, &updates[0], updates.size(),
362 &timeout)); 362 &timeout));
363 363
364 // Error values are stored within updates, so check to make sure that no 364 // Error values are stored within updates, so check to make sure that no
365 // errors occurred. 365 // errors occurred.
366 if (!AreKeventValuesValid(&updates[0], count)) { 366 if (!AreKeventValuesValid(&updates[0], count)) {
367 delegate_->OnFilePathError(target_); 367 callback_.Run(target_, true /* error */);
368 Cancel(); 368 Cancel();
369 return; 369 return;
370 } 370 }
371 371
372 bool update_watches = false; 372 bool update_watches = false;
373 bool send_notification = false; 373 bool send_notification = false;
374 374
375 // Iterate through each of the updates and react to them. 375 // Iterate through each of the updates and react to them.
376 for (int i = 0; i < count; ++i) { 376 for (int i = 0; i < count; ++i) {
377 // Find our kevent record that matches the update notification. 377 // Find our kevent record that matches the update notification.
(...skipping 26 matching lines...) Expand all
404 HandleDeleteOrMoveChange(event, &target_file_affected, &update_watches); 404 HandleDeleteOrMoveChange(event, &target_file_affected, &update_watches);
405 } 405 }
406 if ((updates[i].fflags & NOTE_WRITE) && !target_file_affected) { 406 if ((updates[i].fflags & NOTE_WRITE) && !target_file_affected) {
407 HandleCreateItemChange(event, &target_file_affected, &update_watches); 407 HandleCreateItemChange(event, &target_file_affected, &update_watches);
408 } 408 }
409 send_notification |= target_file_affected; 409 send_notification |= target_file_affected;
410 } 410 }
411 411
412 if (update_watches) { 412 if (update_watches) {
413 if (!UpdateWatches(&send_notification)) { 413 if (!UpdateWatches(&send_notification)) {
414 delegate_->OnFilePathError(target_); 414 callback_.Run(target_, true /* error */);
415 Cancel(); 415 Cancel();
416 } 416 }
417 } 417 }
418 418
419 if (send_notification) { 419 if (send_notification) {
420 delegate_->OnFilePathChanged(target_); 420 callback_.Run(target_, false);
421 } 421 }
422 } 422 }
423 423
424 void FilePathWatcherImpl::OnFileCanWriteWithoutBlocking(int fd) { 424 void FilePathWatcherImpl::OnFileCanWriteWithoutBlocking(int fd) {
425 NOTREACHED(); 425 NOTREACHED();
426 } 426 }
427 427
428 void FilePathWatcherImpl::WillDestroyCurrentMessageLoop() { 428 void FilePathWatcherImpl::WillDestroyCurrentMessageLoop() {
429 CancelOnMessageLoopThread(); 429 CancelOnMessageLoopThread();
430 } 430 }
431 431
432 bool FilePathWatcherImpl::Watch(const FilePath& path, 432 bool FilePathWatcherImpl::Watch(const FilePath& path,
433 bool recursive, 433 bool recursive,
434 FilePathWatcher::Delegate* delegate) { 434 const FilePathWatcher::Callback& callback) {
435 DCHECK(MessageLoopForIO::current()); 435 DCHECK(MessageLoopForIO::current());
436 DCHECK(target_.value().empty()); // Can only watch one path. 436 DCHECK(target_.value().empty()); // Can only watch one path.
437 DCHECK(delegate); 437 DCHECK(!callback.is_null());
438 DCHECK_EQ(kqueue_, -1); 438 DCHECK_EQ(kqueue_, -1);
439 439
440 if (recursive) { 440 if (recursive) {
441 // Recursive watch is not supported on this platform. 441 // Recursive watch is not supported on this platform.
442 NOTIMPLEMENTED(); 442 NOTIMPLEMENTED();
443 return false; 443 return false;
444 } 444 }
445 445
446 delegate_ = delegate; 446 callback_ = callback;
447 target_ = path; 447 target_ = path;
448 448
449 MessageLoop::current()->AddDestructionObserver(this); 449 MessageLoop::current()->AddDestructionObserver(this);
450 io_message_loop_ = base::MessageLoopProxy::current(); 450 io_message_loop_ = base::MessageLoopProxy::current();
451 451
452 kqueue_ = kqueue(); 452 kqueue_ = kqueue();
453 if (kqueue_ == -1) { 453 if (kqueue_ == -1) {
454 DPLOG(ERROR) << "kqueue"; 454 DPLOG(ERROR) << "kqueue";
455 return false; 455 return false;
456 } 456 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 void FilePathWatcherImpl::CancelOnMessageLoopThread() { 492 void FilePathWatcherImpl::CancelOnMessageLoopThread() {
493 DCHECK(MessageLoopForIO::current()); 493 DCHECK(MessageLoopForIO::current());
494 if (!is_cancelled()) { 494 if (!is_cancelled()) {
495 set_cancelled(); 495 set_cancelled();
496 kqueue_watcher_.StopWatchingFileDescriptor(); 496 kqueue_watcher_.StopWatchingFileDescriptor();
497 CloseFileDescriptor(&kqueue_); 497 CloseFileDescriptor(&kqueue_);
498 std::for_each(events_.begin(), events_.end(), ReleaseEvent); 498 std::for_each(events_.begin(), events_.end(), ReleaseEvent);
499 events_.clear(); 499 events_.clear();
500 io_message_loop_ = NULL; 500 io_message_loop_ = NULL;
501 MessageLoop::current()->RemoveDestructionObserver(this); 501 MessageLoop::current()->RemoveDestructionObserver(this);
502 delegate_ = NULL; 502 callback_.Reset();
503 } 503 }
504 } 504 }
505 505
506 } // namespace 506 } // namespace
507 507
508 FilePathWatcher::FilePathWatcher() { 508 FilePathWatcher::FilePathWatcher() {
509 impl_ = new FilePathWatcherImpl(); 509 impl_ = new FilePathWatcherImpl();
510 } 510 }
511 511
512 } // namespace files 512 } // namespace files
513 } // namespace base 513 } // namespace base
OLDNEW
« no previous file with comments | « base/files/file_path_watcher.cc ('k') | base/files/file_path_watcher_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698