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

Side by Side Diff: chrome/browser/devtools/devtools_file_watcher.cc

Issue 2384343002: DevTools: improve DevTools file watcher to send added and removed paths (Closed)
Patch Set: honing skills. Created 4 years, 2 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
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 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/devtools/devtools_file_watcher.h" 5 #include "chrome/browser/devtools/devtools_file_watcher.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <memory> 9 #include <memory>
10 #include <set> 10 #include <set>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/files/file_enumerator.h" 13 #include "base/files/file_enumerator.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/files/file_path_watcher.h" 15 #include "base/files/file_path_watcher.h"
16 #include "base/files/file_util.h"
16 #include "base/memory/ref_counted.h" 17 #include "base/memory/ref_counted.h"
17 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
18 19
19 using content::BrowserThread; 20 using content::BrowserThread;
20 21
21 static int kFirstThrottleTimeout = 10; 22 static int kFirstThrottleTimeout = 10;
22 static int kDefaultThrottleTimeout = 200; 23 static int kDefaultThrottleTimeout = 200;
23 24
24 // DevToolsFileWatcher::SharedFileWatcher -------------------------------------- 25 // DevToolsFileWatcher::SharedFileWatcher --------------------------------------
25 26
26 class DevToolsFileWatcher::SharedFileWatcher : 27 class DevToolsFileWatcher::SharedFileWatcher :
27 public base::RefCounted<SharedFileWatcher> { 28 public base::RefCounted<SharedFileWatcher> {
28 public: 29 public:
29 SharedFileWatcher(); 30 SharedFileWatcher();
30 31
31 void AddListener(DevToolsFileWatcher* watcher); 32 void AddListener(DevToolsFileWatcher* watcher);
32 void RemoveListener(DevToolsFileWatcher* watcher); 33 void RemoveListener(DevToolsFileWatcher* watcher);
33 void AddWatch(const base::FilePath& path); 34 void AddWatch(const base::FilePath& path);
34 void RemoveWatch(const base::FilePath& path); 35 void RemoveWatch(const base::FilePath& path);
35 36
36 private: 37 private:
37 friend class base::RefCounted< 38 friend class base::RefCounted<
38 DevToolsFileWatcher::SharedFileWatcher>; 39 DevToolsFileWatcher::SharedFileWatcher>;
39 ~SharedFileWatcher(); 40 ~SharedFileWatcher();
40 41
42 using FilePathTimesMap = std::map<base::FilePath, base::Time>;
43 void GetModificationTimes(const base::FilePath& path,
44 FilePathTimesMap* file_path_times);
41 void DirectoryChanged(const base::FilePath& path, bool error); 45 void DirectoryChanged(const base::FilePath& path, bool error);
42 void DispatchNotifications(); 46 void DispatchNotifications();
43 47
44 std::vector<DevToolsFileWatcher*> listeners_; 48 std::vector<DevToolsFileWatcher*> listeners_;
45 std::map<base::FilePath, std::unique_ptr<base::FilePathWatcher>> watchers_; 49 std::map<base::FilePath, std::unique_ptr<base::FilePathWatcher>> watchers_;
46 using FilePathTimesMap = std::map<base::FilePath, base::Time>; 50 std::map<base::FilePath, FilePathTimesMap> file_path_times_;
47 FilePathTimesMap file_path_times_;
48 std::set<base::FilePath> pending_paths_; 51 std::set<base::FilePath> pending_paths_;
49 base::Time last_event_time_; 52 base::Time last_event_time_;
50 base::TimeDelta last_dispatch_cost_; 53 base::TimeDelta last_dispatch_cost_;
51 }; 54 };
52 55
53 DevToolsFileWatcher::SharedFileWatcher::SharedFileWatcher() 56 DevToolsFileWatcher::SharedFileWatcher::SharedFileWatcher()
54 : last_dispatch_cost_( 57 : last_dispatch_cost_(
55 base::TimeDelta::FromMilliseconds(kDefaultThrottleTimeout)) { 58 base::TimeDelta::FromMilliseconds(kDefaultThrottleTimeout)) {
56 DevToolsFileWatcher::s_shared_watcher_ = this; 59 DevToolsFileWatcher::s_shared_watcher_ = this;
57 } 60 }
(...skipping 19 matching lines...) Expand all
77 return; 80 return;
78 if (!base::FilePathWatcher::RecursiveWatchAvailable()) 81 if (!base::FilePathWatcher::RecursiveWatchAvailable())
79 return; 82 return;
80 watchers_[path].reset(new base::FilePathWatcher()); 83 watchers_[path].reset(new base::FilePathWatcher());
81 bool success = watchers_[path]->Watch( 84 bool success = watchers_[path]->Watch(
82 path, true, 85 path, true,
83 base::Bind(&SharedFileWatcher::DirectoryChanged, base::Unretained(this))); 86 base::Bind(&SharedFileWatcher::DirectoryChanged, base::Unretained(this)));
84 if (!success) 87 if (!success)
85 return; 88 return;
86 89
90 GetModificationTimes(path, &file_path_times_[path]);
91 }
92
93 void DevToolsFileWatcher::SharedFileWatcher::GetModificationTimes(
94 const base::FilePath& path,
95 FilePathTimesMap* times_map) {
87 base::FileEnumerator enumerator(path, true, base::FileEnumerator::FILES); 96 base::FileEnumerator enumerator(path, true, base::FileEnumerator::FILES);
88 base::FilePath file_path = enumerator.Next(); 97 base::FilePath file_path = enumerator.Next();
89 while (!file_path.empty()) { 98 while (!file_path.empty()) {
90 base::FileEnumerator::FileInfo file_info = enumerator.GetInfo(); 99 base::FileEnumerator::FileInfo file_info = enumerator.GetInfo();
91 file_path_times_[file_path] = file_info.GetLastModifiedTime(); 100 (*times_map)[file_path] = file_info.GetLastModifiedTime();
92 file_path = enumerator.Next(); 101 file_path = enumerator.Next();
93 } 102 }
94 } 103 }
95 104
96 void DevToolsFileWatcher::SharedFileWatcher::RemoveWatch( 105 void DevToolsFileWatcher::SharedFileWatcher::RemoveWatch(
97 const base::FilePath& path) { 106 const base::FilePath& path) {
98 watchers_.erase(path); 107 watchers_.erase(path);
99 } 108 }
100 109
101 void DevToolsFileWatcher::SharedFileWatcher::DirectoryChanged( 110 void DevToolsFileWatcher::SharedFileWatcher::DirectoryChanged(
(...skipping 12 matching lines...) Expand all
114 last_dispatch_cost_ * 2; 123 last_dispatch_cost_ * 2;
115 124
116 BrowserThread::PostDelayedTask( 125 BrowserThread::PostDelayedTask(
117 BrowserThread::FILE, FROM_HERE, 126 BrowserThread::FILE, FROM_HERE,
118 base::Bind(&DevToolsFileWatcher::SharedFileWatcher::DispatchNotifications, 127 base::Bind(&DevToolsFileWatcher::SharedFileWatcher::DispatchNotifications,
119 this), shedule_for); 128 this), shedule_for);
120 last_event_time_ = now; 129 last_event_time_ = now;
121 } 130 }
122 131
123 void DevToolsFileWatcher::SharedFileWatcher::DispatchNotifications() { 132 void DevToolsFileWatcher::SharedFileWatcher::DispatchNotifications() {
133 if (!pending_paths_.size())
134 return;
124 base::Time start = base::Time::Now(); 135 base::Time start = base::Time::Now();
136 std::vector<std::string> added_paths;
137 std::vector<std::string> removed_paths;
125 std::vector<std::string> changed_paths; 138 std::vector<std::string> changed_paths;
126 for (auto path : pending_paths_) { 139
127 base::FileEnumerator enumerator(path, true, base::FileEnumerator::FILES); 140 for (const auto& path : pending_paths_) {
128 base::FilePath file_path = enumerator.Next(); 141 FilePathTimesMap& old_times = file_path_times_[path];
129 while (!file_path.empty()) { 142 FilePathTimesMap current_times;
130 base::FileEnumerator::FileInfo file_info = enumerator.GetInfo(); 143 GetModificationTimes(path, &current_times);
131 base::Time new_time = file_info.GetLastModifiedTime(); 144 for (const auto& path_time : current_times) {
132 if (file_path_times_[file_path] != new_time) { 145 const base::FilePath& path = path_time.first;
133 file_path_times_[file_path] = new_time; 146 auto old_timestamp = old_times.find(path);
134 changed_paths.push_back(file_path.AsUTF8Unsafe()); 147 if (old_timestamp == old_times.end())
135 } 148 added_paths.push_back(path.AsUTF8Unsafe());
136 file_path = enumerator.Next(); 149 else if (old_timestamp->second != path_time.second)
150 changed_paths.push_back(path.AsUTF8Unsafe());
137 } 151 }
152 for (const auto& path_time : old_times) {
153 const base::FilePath& path = path_time.first;
154 if (current_times.find(path) == current_times.end())
155 removed_paths.push_back(path.AsUTF8Unsafe());
156 }
157 old_times.swap(current_times);
138 } 158 }
139 pending_paths_.clear(); 159 pending_paths_.clear();
140 160
141 for (auto* watcher : listeners_) { 161 for (auto* watcher : listeners_) {
142 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 162 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
143 base::Bind(watcher->callback_, changed_paths)); 163 base::Bind(watcher->callback_, changed_paths,
164 added_paths, removed_paths));
144 } 165 }
145 last_dispatch_cost_ = base::Time::Now() - start; 166 last_dispatch_cost_ = base::Time::Now() - start;
146 } 167 }
147 168
148 // static 169 // static
149 DevToolsFileWatcher::SharedFileWatcher* 170 DevToolsFileWatcher::SharedFileWatcher*
150 DevToolsFileWatcher::s_shared_watcher_ = nullptr; 171 DevToolsFileWatcher::s_shared_watcher_ = nullptr;
151 172
152 // DevToolsFileWatcher --------------------------------------------------------- 173 // DevToolsFileWatcher ---------------------------------------------------------
153 174
(...skipping 19 matching lines...) Expand all
173 194
174 void DevToolsFileWatcher::AddWatch(const base::FilePath& path) { 195 void DevToolsFileWatcher::AddWatch(const base::FilePath& path) {
175 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 196 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
176 shared_watcher_->AddWatch(path); 197 shared_watcher_->AddWatch(path);
177 } 198 }
178 199
179 void DevToolsFileWatcher::RemoveWatch(const base::FilePath& path) { 200 void DevToolsFileWatcher::RemoveWatch(const base::FilePath& path) {
180 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 201 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
181 shared_watcher_->RemoveWatch(path); 202 shared_watcher_->RemoveWatch(path);
182 } 203 }
OLDNEW
« no previous file with comments | « chrome/browser/devtools/devtools_file_watcher.h ('k') | chrome/browser/devtools/devtools_ui_bindings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698