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

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

Issue 1113953002: Revert of base: Remove use of MessageLoopProxy (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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"
29 #include "base/posix/eintr_wrapper.h" 31 #include "base/posix/eintr_wrapper.h"
30 #include "base/single_thread_task_runner.h"
31 #include "base/synchronization/lock.h" 32 #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_.task_runner()->PostTask( 267 thread_.message_loop()->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 (!task_runner()->BelongsToCurrentThread()) { 352 if (!message_loop()->BelongsToCurrentThread()) {
353 // Switch to task_runner() to access |watches_| safely. 353 // Switch to message_loop() to access |watches_| safely.
354 task_runner()->PostTask(FROM_HERE, 354 message_loop()->PostTask(
355 Bind(&FilePathWatcherImpl::OnFilePathChanged, this, 355 FROM_HERE,
356 fired_watch, child, created, deleted, is_dir)); 356 Bind(&FilePathWatcherImpl::OnFilePathChanged, this,
357 fired_watch, child, created, deleted, is_dir));
357 return; 358 return;
358 } 359 }
359 360
360 // Check to see if CancelOnMessageLoopThread() has already been called. 361 // Check to see if CancelOnMessageLoopThread() has already been called.
361 // May happen when code flow reaches here from the PostTask() above. 362 // May happen when code flow reaches here from the PostTask() above.
362 if (watches_.empty()) { 363 if (watches_.empty()) {
363 DCHECK(target_.empty()); 364 DCHECK(target_.empty());
364 return; 365 return;
365 } 366 }
366 367
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 callback_.Run(target_, false /* error */); 445 callback_.Run(target_, false /* error */);
445 } 446 }
446 } 447 }
447 448
448 bool FilePathWatcherImpl::Watch(const FilePath& path, 449 bool FilePathWatcherImpl::Watch(const FilePath& path,
449 bool recursive, 450 bool recursive,
450 const FilePathWatcher::Callback& callback) { 451 const FilePathWatcher::Callback& callback) {
451 DCHECK(target_.empty()); 452 DCHECK(target_.empty());
452 DCHECK(MessageLoopForIO::current()); 453 DCHECK(MessageLoopForIO::current());
453 454
454 set_task_runner(ThreadTaskRunnerHandle::Get()); 455 set_message_loop(MessageLoopProxy::current());
455 callback_ = callback; 456 callback_ = callback;
456 target_ = path; 457 target_ = path;
457 recursive_ = recursive; 458 recursive_ = recursive;
458 MessageLoop::current()->AddDestructionObserver(this); 459 MessageLoop::current()->AddDestructionObserver(this);
459 460
460 std::vector<FilePath::StringType> comps; 461 std::vector<FilePath::StringType> comps;
461 target_.GetComponents(&comps); 462 target_.GetComponents(&comps);
462 DCHECK(!comps.empty()); 463 DCHECK(!comps.empty());
463 for (size_t i = 1; i < comps.size(); ++i) 464 for (size_t i = 1; i < comps.size(); ++i)
464 watches_.push_back(WatchEntry(comps[i])); 465 watches_.push_back(WatchEntry(comps[i]));
465 watches_.push_back(WatchEntry(FilePath::StringType())); 466 watches_.push_back(WatchEntry(FilePath::StringType()));
466 UpdateWatches(); 467 UpdateWatches();
467 return true; 468 return true;
468 } 469 }
469 470
470 void FilePathWatcherImpl::Cancel() { 471 void FilePathWatcherImpl::Cancel() {
471 if (callback_.is_null()) { 472 if (callback_.is_null()) {
472 // Watch was never called, or the message_loop() thread is already gone. 473 // Watch was never called, or the message_loop() thread is already gone.
473 set_cancelled(); 474 set_cancelled();
474 return; 475 return;
475 } 476 }
476 477
477 // Switch to the message_loop() if necessary so we can access |watches_|. 478 // Switch to the message_loop() if necessary so we can access |watches_|.
478 if (!task_runner()->BelongsToCurrentThread()) { 479 if (!message_loop()->BelongsToCurrentThread()) {
479 task_runner()->PostTask(FROM_HERE, Bind(&FilePathWatcher::CancelWatch, 480 message_loop()->PostTask(FROM_HERE,
480 make_scoped_refptr(this))); 481 Bind(&FilePathWatcher::CancelWatch,
482 make_scoped_refptr(this)));
481 } else { 483 } else {
482 CancelOnMessageLoopThread(); 484 CancelOnMessageLoopThread();
483 } 485 }
484 } 486 }
485 487
486 void FilePathWatcherImpl::CancelOnMessageLoopThread() { 488 void FilePathWatcherImpl::CancelOnMessageLoopThread() {
487 DCHECK(task_runner()->BelongsToCurrentThread()); 489 DCHECK(message_loop()->BelongsToCurrentThread());
488 set_cancelled(); 490 set_cancelled();
489 491
490 if (!callback_.is_null()) { 492 if (!callback_.is_null()) {
491 MessageLoop::current()->RemoveDestructionObserver(this); 493 MessageLoop::current()->RemoveDestructionObserver(this);
492 callback_.Reset(); 494 callback_.Reset();
493 } 495 }
494 496
495 for (size_t i = 0; i < watches_.size(); ++i) 497 for (size_t i = 0; i < watches_.size(); ++i)
496 g_inotify_reader.Get().RemoveWatch(watches_[i].watch, this); 498 g_inotify_reader.Get().RemoveWatch(watches_[i].watch, this);
497 watches_.clear(); 499 watches_.clear();
498 target_.clear(); 500 target_.clear();
499 501
500 if (recursive_) 502 if (recursive_)
501 RemoveRecursiveWatches(); 503 RemoveRecursiveWatches();
502 } 504 }
503 505
504 void FilePathWatcherImpl::WillDestroyCurrentMessageLoop() { 506 void FilePathWatcherImpl::WillDestroyCurrentMessageLoop() {
505 CancelOnMessageLoopThread(); 507 CancelOnMessageLoopThread();
506 } 508 }
507 509
508 void FilePathWatcherImpl::UpdateWatches() { 510 void FilePathWatcherImpl::UpdateWatches() {
509 // Ensure this runs on the message_loop() exclusively in order to avoid 511 // Ensure this runs on the message_loop() exclusively in order to avoid
510 // concurrency issues. 512 // concurrency issues.
511 DCHECK(task_runner()->BelongsToCurrentThread()); 513 DCHECK(message_loop()->BelongsToCurrentThread());
512 DCHECK(HasValidWatchVector()); 514 DCHECK(HasValidWatchVector());
513 515
514 // Walk the list of watches and update them as we go. 516 // Walk the list of watches and update them as we go.
515 FilePath path(FILE_PATH_LITERAL("/")); 517 FilePath path(FILE_PATH_LITERAL("/"));
516 bool path_valid = true; 518 bool path_valid = true;
517 for (size_t i = 0; i < watches_.size(); ++i) { 519 for (size_t i = 0; i < watches_.size(); ++i) {
518 WatchEntry& watch_entry = watches_[i]; 520 WatchEntry& watch_entry = watches_[i];
519 InotifyReader::Watch old_watch = watch_entry.watch; 521 InotifyReader::Watch old_watch = watch_entry.watch;
520 watch_entry.watch = InotifyReader::kInvalidWatch; 522 watch_entry.watch = InotifyReader::kInvalidWatch;
521 watch_entry.linkname.clear(); 523 watch_entry.linkname.clear();
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 return watches_[watches_.size() - 1].subdir.empty(); 683 return watches_[watches_.size() - 1].subdir.empty();
682 } 684 }
683 685
684 } // namespace 686 } // namespace
685 687
686 FilePathWatcher::FilePathWatcher() { 688 FilePathWatcher::FilePathWatcher() {
687 impl_ = new FilePathWatcherImpl(); 689 impl_ = new FilePathWatcherImpl();
688 } 690 }
689 691
690 } // namespace base 692 } // 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