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

Side by Side Diff: chrome/browser/file_path_watcher/file_path_watcher_inotify.cc

Issue 5711001: Add a new GetInstance() method for remaining files with singleton classes under chrome/browser. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 10 years 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/file_path_watcher/file_path_watcher.h" 5 #include "chrome/browser/file_path_watcher/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 <set> 15 #include <set>
16 #include <utility> 16 #include <utility>
17 #include <vector> 17 #include <vector>
18 18
19 #include "base/eintr_wrapper.h" 19 #include "base/eintr_wrapper.h"
20 #include "base/file_path.h" 20 #include "base/file_path.h"
21 #include "base/file_util.h" 21 #include "base/file_util.h"
22 #include "base/hash_tables.h" 22 #include "base/hash_tables.h"
23 #include "base/lazy_instance.h"
23 #include "base/lock.h" 24 #include "base/lock.h"
24 #include "base/logging.h" 25 #include "base/logging.h"
25 #include "base/message_loop.h" 26 #include "base/message_loop.h"
26 #include "base/scoped_ptr.h" 27 #include "base/scoped_ptr.h"
27 #include "base/singleton.h"
28 #include "base/task.h" 28 #include "base/task.h"
29 #include "base/thread.h" 29 #include "base/thread.h"
30 30
31 namespace { 31 namespace {
32 32
33 class FilePathWatcherImpl; 33 class FilePathWatcherImpl;
34 34
35 // Singleton to manage all inotify watches. 35 // Singleton to manage all inotify watches.
36 // TODO(tony): It would be nice if this wasn't a singleton. 36 // TODO(tony): It would be nice if this wasn't a singleton.
37 // http://crbug.com/38174 37 // http://crbug.com/38174
38 class InotifyReader { 38 class InotifyReader {
39 public: 39 public:
40 typedef int Watch; // Watch descriptor used by AddWatch and RemoveWatch. 40 typedef int Watch; // Watch descriptor used by AddWatch and RemoveWatch.
41 static const Watch kInvalidWatch = -1; 41 static const Watch kInvalidWatch = -1;
42 42
43 // Watch directory |path| for changes. |watcher| will be notified on each 43 // Watch directory |path| for changes. |watcher| will be notified on each
44 // change. Returns kInvalidWatch on failure. 44 // change. Returns kInvalidWatch on failure.
45 Watch AddWatch(const FilePath& path, FilePathWatcherImpl* watcher); 45 Watch AddWatch(const FilePath& path, FilePathWatcherImpl* watcher);
46 46
47 // Remove |watch|. Returns true on success. 47 // Remove |watch|. Returns true on success.
48 bool RemoveWatch(Watch watch, FilePathWatcherImpl* watcher); 48 bool RemoveWatch(Watch watch, FilePathWatcherImpl* watcher);
49 49
50 // Callback for InotifyReaderTask. 50 // Callback for InotifyReaderTask.
51 void OnInotifyEvent(const inotify_event* event); 51 void OnInotifyEvent(const inotify_event* event);
52 52
53 private: 53 private:
54 friend struct DefaultSingletonTraits<InotifyReader>; 54 friend struct ::base::DefaultLazyInstanceTraits<InotifyReader>;
55 55
56 typedef std::set<FilePathWatcherImpl*> WatcherSet; 56 typedef std::set<FilePathWatcherImpl*> WatcherSet;
57 57
58 InotifyReader(); 58 InotifyReader();
59 ~InotifyReader(); 59 ~InotifyReader();
60 60
61 // We keep track of which delegates want to be notified on which watches. 61 // We keep track of which delegates want to be notified on which watches.
62 base::hash_map<Watch, WatcherSet> watchers_; 62 base::hash_map<Watch, WatcherSet> watchers_;
63 63
64 // Lock to protect watchers_. 64 // Lock to protect watchers_.
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 } 192 }
193 193
194 private: 194 private:
195 InotifyReader* reader_; 195 InotifyReader* reader_;
196 int inotify_fd_; 196 int inotify_fd_;
197 int shutdown_fd_; 197 int shutdown_fd_;
198 198
199 DISALLOW_COPY_AND_ASSIGN(InotifyReaderTask); 199 DISALLOW_COPY_AND_ASSIGN(InotifyReaderTask);
200 }; 200 };
201 201
202 static base::LazyInstance<InotifyReader> g_inotify_reader(
203 base::LINKER_INITIALIZED);
204
202 InotifyReader::InotifyReader() 205 InotifyReader::InotifyReader()
203 : thread_("inotify_reader"), 206 : thread_("inotify_reader"),
204 inotify_fd_(inotify_init()), 207 inotify_fd_(inotify_init()),
205 valid_(false) { 208 valid_(false) {
206 shutdown_pipe_[0] = -1; 209 shutdown_pipe_[0] = -1;
207 shutdown_pipe_[1] = -1; 210 shutdown_pipe_[1] = -1;
208 if (inotify_fd_ >= 0 && pipe(shutdown_pipe_) == 0 && thread_.Start()) { 211 if (inotify_fd_ >= 0 && pipe(shutdown_pipe_) == 0 && thread_.Start()) {
209 thread_.message_loop()->PostTask( 212 thread_.message_loop()->PostTask(
210 FROM_HERE, new InotifyReaderTask(this, inotify_fd_, shutdown_pipe_[0])); 213 FROM_HERE, new InotifyReaderTask(this, inotify_fd_, shutdown_pipe_[0]));
211 valid_ = true; 214 valid_ = true;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 // Switch to the file thread if necessary so we can access |watches_|. 362 // Switch to the file thread if necessary so we can access |watches_|.
360 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) { 363 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
361 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 364 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
362 NewRunnableMethod(this, &FilePathWatcherImpl::Cancel)); 365 NewRunnableMethod(this, &FilePathWatcherImpl::Cancel));
363 return; 366 return;
364 } 367 }
365 368
366 for (WatchVector::iterator watch_entry(watches_.begin()); 369 for (WatchVector::iterator watch_entry(watches_.begin());
367 watch_entry != watches_.end(); ++watch_entry) { 370 watch_entry != watches_.end(); ++watch_entry) {
368 if (watch_entry->watch_ != InotifyReader::kInvalidWatch) 371 if (watch_entry->watch_ != InotifyReader::kInvalidWatch)
369 Singleton<InotifyReader>::get()->RemoveWatch(watch_entry->watch_, this); 372 g_inotify_reader.Get().RemoveWatch(watch_entry->watch_, this);
370 } 373 }
371 watches_.clear(); 374 watches_.clear();
372 delegate_ = NULL; 375 delegate_ = NULL;
373 target_.clear(); 376 target_.clear();
374 } 377 }
375 378
376 bool FilePathWatcherImpl::UpdateWatches() { 379 bool FilePathWatcherImpl::UpdateWatches() {
377 // Ensure this runs on the file thread exclusively in order to avoid 380 // Ensure this runs on the file thread exclusively in order to avoid
378 // concurrency issues. 381 // concurrency issues.
379 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
380 383
381 // Walk the list of watches and update them as we go. 384 // Walk the list of watches and update them as we go.
382 FilePath path(FILE_PATH_LITERAL("/")); 385 FilePath path(FILE_PATH_LITERAL("/"));
383 bool path_valid = true; 386 bool path_valid = true;
384 for (WatchVector::iterator watch_entry(watches_.begin()); 387 for (WatchVector::iterator watch_entry(watches_.begin());
385 watch_entry != watches_.end(); ++watch_entry) { 388 watch_entry != watches_.end(); ++watch_entry) {
386 InotifyReader::Watch old_watch = watch_entry->watch_; 389 InotifyReader::Watch old_watch = watch_entry->watch_;
387 if (path_valid) { 390 if (path_valid) {
388 watch_entry->watch_ = 391 watch_entry->watch_ = g_inotify_reader.Get().AddWatch(path, this);
389 Singleton<InotifyReader>::get()->AddWatch(path, this);
390 if (watch_entry->watch_ == InotifyReader::kInvalidWatch) { 392 if (watch_entry->watch_ == InotifyReader::kInvalidWatch) {
391 path_valid = false; 393 path_valid = false;
392 } 394 }
393 } else { 395 } else {
394 watch_entry->watch_ = InotifyReader::kInvalidWatch; 396 watch_entry->watch_ = InotifyReader::kInvalidWatch;
395 } 397 }
396 if (old_watch != InotifyReader::kInvalidWatch && 398 if (old_watch != InotifyReader::kInvalidWatch &&
397 old_watch != watch_entry->watch_) { 399 old_watch != watch_entry->watch_) {
398 Singleton<InotifyReader>::get()->RemoveWatch(old_watch, this); 400 g_inotify_reader.Get().RemoveWatch(old_watch, this);
399 } 401 }
400 path = path.Append(watch_entry->subdir_); 402 path = path.Append(watch_entry->subdir_);
401 } 403 }
402 404
403 return true; 405 return true;
404 } 406 }
405 407
406 } // namespace 408 } // namespace
407 409
408 FilePathWatcher::FilePathWatcher() { 410 FilePathWatcher::FilePathWatcher() {
409 impl_ = new FilePathWatcherImpl(); 411 impl_ = new FilePathWatcherImpl();
410 } 412 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698