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

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

Issue 1100773004: base: Remove most uses of MessageLoopProxy (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added some missing includes. Created 5 years, 7 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
« no previous file with comments | « base/files/file_path_watcher_kqueue.cc ('k') | base/files/file_path_watcher_unittest.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 <errno.h> 7 #include <errno.h>
8 #include <string.h> 8 #include <string.h>
9 #include <sys/inotify.h> 9 #include <sys/inotify.h>
10 #include <sys/ioctl.h> 10 #include <sys/ioctl.h>
11 #include <sys/select.h> 11 #include <sys/select.h>
12 #include <unistd.h> 12 #include <unistd.h>
13 13
14 #include <algorithm> 14 #include <algorithm>
15 #include <map> 15 #include <map>
16 #include <set> 16 #include <set>
17 #include <utility> 17 #include <utility>
18 #include <vector> 18 #include <vector>
19 19
20 #include "base/bind.h" 20 #include "base/bind.h"
21 #include "base/containers/hash_tables.h" 21 #include "base/containers/hash_tables.h"
22 #include "base/files/file_enumerator.h" 22 #include "base/files/file_enumerator.h"
23 #include "base/files/file_path.h" 23 #include "base/files/file_path.h"
24 #include "base/files/file_util.h" 24 #include "base/files/file_util.h"
25 #include "base/lazy_instance.h" 25 #include "base/lazy_instance.h"
26 #include "base/location.h" 26 #include "base/location.h"
27 #include "base/logging.h" 27 #include "base/logging.h"
28 #include "base/memory/scoped_ptr.h" 28 #include "base/memory/scoped_ptr.h"
29 #include "base/message_loop/message_loop.h"
30 #include "base/message_loop/message_loop_proxy.h"
31 #include "base/posix/eintr_wrapper.h" 29 #include "base/posix/eintr_wrapper.h"
30 #include "base/single_thread_task_runner.h"
32 #include "base/synchronization/lock.h" 31 #include "base/synchronization/lock.h"
32 #include "base/thread_task_runner_handle.h"
33 #include "base/threading/thread.h" 33 #include "base/threading/thread.h"
34 #include "base/trace_event/trace_event.h" 34 #include "base/trace_event/trace_event.h"
35 35
36 namespace base { 36 namespace base {
37 37
38 namespace { 38 namespace {
39 39
40 class FilePathWatcherImpl; 40 class FilePathWatcherImpl;
41 41
42 // Singleton to manage all inotify watches. 42 // Singleton to manage all inotify watches.
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 InotifyReader::InotifyReader() 257 InotifyReader::InotifyReader()
258 : thread_("inotify_reader"), 258 : thread_("inotify_reader"),
259 inotify_fd_(inotify_init()), 259 inotify_fd_(inotify_init()),
260 valid_(false) { 260 valid_(false) {
261 if (inotify_fd_ < 0) 261 if (inotify_fd_ < 0)
262 PLOG(ERROR) << "inotify_init() failed"; 262 PLOG(ERROR) << "inotify_init() failed";
263 263
264 shutdown_pipe_[0] = -1; 264 shutdown_pipe_[0] = -1;
265 shutdown_pipe_[1] = -1; 265 shutdown_pipe_[1] = -1;
266 if (inotify_fd_ >= 0 && pipe(shutdown_pipe_) == 0 && thread_.Start()) { 266 if (inotify_fd_ >= 0 && pipe(shutdown_pipe_) == 0 && thread_.Start()) {
267 thread_.message_loop()->PostTask( 267 thread_.task_runner()->PostTask(
268 FROM_HERE, 268 FROM_HERE,
269 Bind(&InotifyReaderCallback, this, inotify_fd_, shutdown_pipe_[0])); 269 Bind(&InotifyReaderCallback, this, inotify_fd_, shutdown_pipe_[0]));
270 valid_ = true; 270 valid_ = true;
271 } 271 }
272 } 272 }
273 273
274 InotifyReader::~InotifyReader() { 274 InotifyReader::~InotifyReader() {
275 if (valid_) { 275 if (valid_) {
276 // Write to the self-pipe so that the select call in InotifyReaderTask 276 // Write to the self-pipe so that the select call in InotifyReaderTask
277 // returns. 277 // returns.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 342
343 FilePathWatcherImpl::FilePathWatcherImpl() 343 FilePathWatcherImpl::FilePathWatcherImpl()
344 : recursive_(false) { 344 : recursive_(false) {
345 } 345 }
346 346
347 void FilePathWatcherImpl::OnFilePathChanged(InotifyReader::Watch fired_watch, 347 void FilePathWatcherImpl::OnFilePathChanged(InotifyReader::Watch fired_watch,
348 const FilePath::StringType& child, 348 const FilePath::StringType& child,
349 bool created, 349 bool created,
350 bool deleted, 350 bool deleted,
351 bool is_dir) { 351 bool is_dir) {
352 if (!message_loop()->BelongsToCurrentThread()) { 352 if (!task_runner()->BelongsToCurrentThread()) {
353 // Switch to message_loop() to access |watches_| safely. 353 // Switch to task_runner() to access |watches_| safely.
354 message_loop()->PostTask( 354 task_runner()->PostTask(FROM_HERE,
355 FROM_HERE, 355 Bind(&FilePathWatcherImpl::OnFilePathChanged, this,
356 Bind(&FilePathWatcherImpl::OnFilePathChanged, this, 356 fired_watch, child, created, deleted, is_dir));
357 fired_watch, child, created, deleted, is_dir));
358 return; 357 return;
359 } 358 }
360 359
361 // Check to see if CancelOnMessageLoopThread() has already been called. 360 // Check to see if CancelOnMessageLoopThread() has already been called.
362 // May happen when code flow reaches here from the PostTask() above. 361 // May happen when code flow reaches here from the PostTask() above.
363 if (watches_.empty()) { 362 if (watches_.empty()) {
364 DCHECK(target_.empty()); 363 DCHECK(target_.empty());
365 return; 364 return;
366 } 365 }
367 366
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 callback_.Run(target_, false /* error */); 444 callback_.Run(target_, false /* error */);
446 } 445 }
447 } 446 }
448 447
449 bool FilePathWatcherImpl::Watch(const FilePath& path, 448 bool FilePathWatcherImpl::Watch(const FilePath& path,
450 bool recursive, 449 bool recursive,
451 const FilePathWatcher::Callback& callback) { 450 const FilePathWatcher::Callback& callback) {
452 DCHECK(target_.empty()); 451 DCHECK(target_.empty());
453 DCHECK(MessageLoopForIO::current()); 452 DCHECK(MessageLoopForIO::current());
454 453
455 set_message_loop(MessageLoopProxy::current()); 454 set_task_runner(ThreadTaskRunnerHandle::Get());
456 callback_ = callback; 455 callback_ = callback;
457 target_ = path; 456 target_ = path;
458 recursive_ = recursive; 457 recursive_ = recursive;
459 MessageLoop::current()->AddDestructionObserver(this); 458 MessageLoop::current()->AddDestructionObserver(this);
460 459
461 std::vector<FilePath::StringType> comps; 460 std::vector<FilePath::StringType> comps;
462 target_.GetComponents(&comps); 461 target_.GetComponents(&comps);
463 DCHECK(!comps.empty()); 462 DCHECK(!comps.empty());
464 for (size_t i = 1; i < comps.size(); ++i) 463 for (size_t i = 1; i < comps.size(); ++i)
465 watches_.push_back(WatchEntry(comps[i])); 464 watches_.push_back(WatchEntry(comps[i]));
466 watches_.push_back(WatchEntry(FilePath::StringType())); 465 watches_.push_back(WatchEntry(FilePath::StringType()));
467 UpdateWatches(); 466 UpdateWatches();
468 return true; 467 return true;
469 } 468 }
470 469
471 void FilePathWatcherImpl::Cancel() { 470 void FilePathWatcherImpl::Cancel() {
472 if (callback_.is_null()) { 471 if (callback_.is_null()) {
473 // Watch was never called, or the message_loop() thread is already gone. 472 // Watch was never called, or the message_loop() thread is already gone.
474 set_cancelled(); 473 set_cancelled();
475 return; 474 return;
476 } 475 }
477 476
478 // Switch to the message_loop() if necessary so we can access |watches_|. 477 // Switch to the message_loop() if necessary so we can access |watches_|.
479 if (!message_loop()->BelongsToCurrentThread()) { 478 if (!task_runner()->BelongsToCurrentThread()) {
480 message_loop()->PostTask(FROM_HERE, 479 task_runner()->PostTask(FROM_HERE, Bind(&FilePathWatcher::CancelWatch,
481 Bind(&FilePathWatcher::CancelWatch, 480 make_scoped_refptr(this)));
482 make_scoped_refptr(this)));
483 } else { 481 } else {
484 CancelOnMessageLoopThread(); 482 CancelOnMessageLoopThread();
485 } 483 }
486 } 484 }
487 485
488 void FilePathWatcherImpl::CancelOnMessageLoopThread() { 486 void FilePathWatcherImpl::CancelOnMessageLoopThread() {
489 DCHECK(message_loop()->BelongsToCurrentThread()); 487 DCHECK(task_runner()->BelongsToCurrentThread());
490 set_cancelled(); 488 set_cancelled();
491 489
492 if (!callback_.is_null()) { 490 if (!callback_.is_null()) {
493 MessageLoop::current()->RemoveDestructionObserver(this); 491 MessageLoop::current()->RemoveDestructionObserver(this);
494 callback_.Reset(); 492 callback_.Reset();
495 } 493 }
496 494
497 for (size_t i = 0; i < watches_.size(); ++i) 495 for (size_t i = 0; i < watches_.size(); ++i)
498 g_inotify_reader.Get().RemoveWatch(watches_[i].watch, this); 496 g_inotify_reader.Get().RemoveWatch(watches_[i].watch, this);
499 watches_.clear(); 497 watches_.clear();
500 target_.clear(); 498 target_.clear();
501 499
502 if (recursive_) 500 if (recursive_)
503 RemoveRecursiveWatches(); 501 RemoveRecursiveWatches();
504 } 502 }
505 503
506 void FilePathWatcherImpl::WillDestroyCurrentMessageLoop() { 504 void FilePathWatcherImpl::WillDestroyCurrentMessageLoop() {
507 CancelOnMessageLoopThread(); 505 CancelOnMessageLoopThread();
508 } 506 }
509 507
510 void FilePathWatcherImpl::UpdateWatches() { 508 void FilePathWatcherImpl::UpdateWatches() {
511 // Ensure this runs on the message_loop() exclusively in order to avoid 509 // Ensure this runs on the message_loop() exclusively in order to avoid
512 // concurrency issues. 510 // concurrency issues.
513 DCHECK(message_loop()->BelongsToCurrentThread()); 511 DCHECK(task_runner()->BelongsToCurrentThread());
514 DCHECK(HasValidWatchVector()); 512 DCHECK(HasValidWatchVector());
515 513
516 // Walk the list of watches and update them as we go. 514 // Walk the list of watches and update them as we go.
517 FilePath path(FILE_PATH_LITERAL("/")); 515 FilePath path(FILE_PATH_LITERAL("/"));
518 bool path_valid = true; 516 bool path_valid = true;
519 for (size_t i = 0; i < watches_.size(); ++i) { 517 for (size_t i = 0; i < watches_.size(); ++i) {
520 WatchEntry& watch_entry = watches_[i]; 518 WatchEntry& watch_entry = watches_[i];
521 InotifyReader::Watch old_watch = watch_entry.watch; 519 InotifyReader::Watch old_watch = watch_entry.watch;
522 watch_entry.watch = InotifyReader::kInvalidWatch; 520 watch_entry.watch = InotifyReader::kInvalidWatch;
523 watch_entry.linkname.clear(); 521 watch_entry.linkname.clear();
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 return watches_[watches_.size() - 1].subdir.empty(); 681 return watches_[watches_.size() - 1].subdir.empty();
684 } 682 }
685 683
686 } // namespace 684 } // namespace
687 685
688 FilePathWatcher::FilePathWatcher() { 686 FilePathWatcher::FilePathWatcher() {
689 impl_ = new FilePathWatcherImpl(); 687 impl_ = new FilePathWatcherImpl();
690 } 688 }
691 689
692 } // namespace base 690 } // namespace base
OLDNEW
« no previous file with comments | « base/files/file_path_watcher_kqueue.cc ('k') | base/files/file_path_watcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698