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

Side by Side Diff: base/files/file_path_watcher_fsevents.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.h ('k') | base/files/file_path_watcher_kqueue.h » ('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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_fsevents.h" 5 #include "base/files/file_path_watcher_fsevents.h"
6 6
7 #include <list> 7 #include <list>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/mac/libdispatch_task_runner.h" 13 #include "base/mac/libdispatch_task_runner.h"
14 #include "base/mac/scoped_cftyperef.h" 14 #include "base/mac/scoped_cftyperef.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/thread_task_runner_handle.h"
16 17
17 namespace base { 18 namespace base {
18 19
19 namespace { 20 namespace {
20 21
21 // The latency parameter passed to FSEventsStreamCreate(). 22 // The latency parameter passed to FSEventsStreamCreate().
22 const CFAbsoluteTime kEventLatencySeconds = 0.3; 23 const CFAbsoluteTime kEventLatencySeconds = 0.3;
23 24
24 class FSEventsTaskRunner : public mac::LibDispatchTaskRunner { 25 class FSEventsTaskRunner : public mac::LibDispatchTaskRunner {
25 public: 26 public:
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 const FilePathWatcher::Callback& callback) { 86 const FilePathWatcher::Callback& callback) {
86 DCHECK(MessageLoopForIO::current()); 87 DCHECK(MessageLoopForIO::current());
87 DCHECK(!callback.is_null()); 88 DCHECK(!callback.is_null());
88 DCHECK(callback_.is_null()); 89 DCHECK(callback_.is_null());
89 90
90 // This class could support non-recursive watches, but that is currently 91 // This class could support non-recursive watches, but that is currently
91 // left to FilePathWatcherKQueue. 92 // left to FilePathWatcherKQueue.
92 if (!recursive) 93 if (!recursive)
93 return false; 94 return false;
94 95
95 set_message_loop(MessageLoopProxy::current()); 96 set_task_runner(ThreadTaskRunnerHandle::Get());
96 callback_ = callback; 97 callback_ = callback;
97 98
98 FSEventStreamEventId start_event = FSEventsGetCurrentEventId(); 99 FSEventStreamEventId start_event = FSEventsGetCurrentEventId();
99 g_task_runner.Get().PostTask( 100 g_task_runner.Get().PostTask(
100 FROM_HERE, Bind(&FilePathWatcherFSEvents::StartEventStream, this, 101 FROM_HERE, Bind(&FilePathWatcherFSEvents::StartEventStream, this,
101 start_event, path)); 102 start_event, path));
102 return true; 103 return true;
103 } 104 }
104 105
105 void FilePathWatcherFSEvents::Cancel() { 106 void FilePathWatcherFSEvents::Cancel() {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 g_task_runner.Get().PostTask( 146 g_task_runner.Get().PostTask(
146 FROM_HERE, 147 FROM_HERE,
147 Bind(&FilePathWatcherFSEvents::UpdateEventStream, watcher, 148 Bind(&FilePathWatcherFSEvents::UpdateEventStream, watcher,
148 root_change_at)); 149 root_change_at));
149 } 150 }
150 151
151 watcher->OnFilePathsChanged(paths); 152 watcher->OnFilePathsChanged(paths);
152 } 153 }
153 154
154 FilePathWatcherFSEvents::~FilePathWatcherFSEvents() { 155 FilePathWatcherFSEvents::~FilePathWatcherFSEvents() {
155 // This method may be called on either the libdispatch or message_loop() 156 // This method may be called on either the libdispatch or task_runner()
156 // thread. Checking callback_ on the libdispatch thread here is safe because 157 // thread. Checking callback_ on the libdispatch thread here is safe because
157 // it is executing in a task posted by Cancel() which first reset callback_. 158 // it is executing in a task posted by Cancel() which first reset callback_.
158 // PostTask forms a sufficient memory barrier to ensure that the value is 159 // PostTask forms a sufficient memory barrier to ensure that the value is
159 // consistent on the target thread. 160 // consistent on the target thread.
160 DCHECK(callback_.is_null()) 161 DCHECK(callback_.is_null())
161 << "Cancel() must be called before FilePathWatcher is destroyed."; 162 << "Cancel() must be called before FilePathWatcher is destroyed.";
162 } 163 }
163 164
164 void FilePathWatcherFSEvents::OnFilePathsChanged( 165 void FilePathWatcherFSEvents::OnFilePathsChanged(
165 const std::vector<FilePath>& paths) { 166 const std::vector<FilePath>& paths) {
166 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread()); 167 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread());
167 DCHECK(!resolved_target_.empty()); 168 DCHECK(!resolved_target_.empty());
168 message_loop()->PostTask( 169 task_runner()->PostTask(
169 FROM_HERE, Bind(&FilePathWatcherFSEvents::DispatchEvents, this, paths, 170 FROM_HERE, Bind(&FilePathWatcherFSEvents::DispatchEvents, this, paths,
170 target_, resolved_target_)); 171 target_, resolved_target_));
171 } 172 }
172 173
173 void FilePathWatcherFSEvents::DispatchEvents(const std::vector<FilePath>& paths, 174 void FilePathWatcherFSEvents::DispatchEvents(const std::vector<FilePath>& paths,
174 const FilePath& target, 175 const FilePath& target,
175 const FilePath& resolved_target) { 176 const FilePath& resolved_target) {
176 DCHECK(message_loop()->RunsTasksOnCurrentThread()); 177 DCHECK(task_runner()->RunsTasksOnCurrentThread());
177 178
178 // Don't issue callbacks after Cancel() has been called. 179 // Don't issue callbacks after Cancel() has been called.
179 if (is_cancelled() || callback_.is_null()) { 180 if (is_cancelled() || callback_.is_null()) {
180 return; 181 return;
181 } 182 }
182 183
183 for (const FilePath& path : paths) { 184 for (const FilePath& path : paths) {
184 if (resolved_target.IsParent(path) || resolved_target == path) { 185 if (resolved_target.IsParent(path) || resolved_target == path) {
185 callback_.Run(target, false); 186 callback_.Run(target, false);
186 return; 187 return;
187 } 188 }
188 } 189 }
189 } 190 }
190 191
191 void FilePathWatcherFSEvents::CancelOnMessageLoopThread() { 192 void FilePathWatcherFSEvents::CancelOnMessageLoopThread() {
192 // For all other implementations, the "message loop thread" is the IO thread, 193 // For all other implementations, the "message loop thread" is the IO thread,
193 // as returned by message_loop(). This implementation, however, needs to 194 // as returned by task_runner(). This implementation, however, needs to
194 // cancel pending work on the Dispatch Queue thread. 195 // cancel pending work on the Dispatch Queue thread.
195 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread()); 196 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread());
196 197
197 if (fsevent_stream_) { 198 if (fsevent_stream_) {
198 DestroyEventStream(); 199 DestroyEventStream();
199 target_.clear(); 200 target_.clear();
200 resolved_target_.clear(); 201 resolved_target_.clear();
201 } 202 }
202 } 203 }
203 204
(...skipping 28 matching lines...) Expand all
232 233
233 fsevent_stream_ = FSEventStreamCreate(NULL, &FSEventsCallback, &context, 234 fsevent_stream_ = FSEventStreamCreate(NULL, &FSEventsCallback, &context,
234 watched_paths, 235 watched_paths,
235 start_event, 236 start_event,
236 kEventLatencySeconds, 237 kEventLatencySeconds,
237 kFSEventStreamCreateFlagWatchRoot); 238 kFSEventStreamCreateFlagWatchRoot);
238 FSEventStreamSetDispatchQueue(fsevent_stream_, 239 FSEventStreamSetDispatchQueue(fsevent_stream_,
239 g_task_runner.Get().GetDispatchQueue()); 240 g_task_runner.Get().GetDispatchQueue());
240 241
241 if (!FSEventStreamStart(fsevent_stream_)) { 242 if (!FSEventStreamStart(fsevent_stream_)) {
242 message_loop()->PostTask( 243 task_runner()->PostTask(
243 FROM_HERE, Bind(&FilePathWatcherFSEvents::ReportError, this, target_)); 244 FROM_HERE, Bind(&FilePathWatcherFSEvents::ReportError, this, target_));
244 } 245 }
245 } 246 }
246 247
247 bool FilePathWatcherFSEvents::ResolveTargetPath() { 248 bool FilePathWatcherFSEvents::ResolveTargetPath() {
248 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread()); 249 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread());
249 FilePath resolved = ResolvePath(target_).StripTrailingSeparators(); 250 FilePath resolved = ResolvePath(target_).StripTrailingSeparators();
250 bool changed = resolved != resolved_target_; 251 bool changed = resolved != resolved_target_;
251 resolved_target_ = resolved; 252 resolved_target_ = resolved;
252 if (resolved_target_.empty()) { 253 if (resolved_target_.empty()) {
253 message_loop()->PostTask( 254 task_runner()->PostTask(
254 FROM_HERE, Bind(&FilePathWatcherFSEvents::ReportError, this, target_)); 255 FROM_HERE, Bind(&FilePathWatcherFSEvents::ReportError, this, target_));
255 } 256 }
256 return changed; 257 return changed;
257 } 258 }
258 259
259 void FilePathWatcherFSEvents::ReportError(const FilePath& target) { 260 void FilePathWatcherFSEvents::ReportError(const FilePath& target) {
260 DCHECK(message_loop()->RunsTasksOnCurrentThread()); 261 DCHECK(task_runner()->RunsTasksOnCurrentThread());
261 if (!callback_.is_null()) { 262 if (!callback_.is_null()) {
262 callback_.Run(target, true); 263 callback_.Run(target, true);
263 } 264 }
264 } 265 }
265 266
266 void FilePathWatcherFSEvents::DestroyEventStream() { 267 void FilePathWatcherFSEvents::DestroyEventStream() {
267 FSEventStreamStop(fsevent_stream_); 268 FSEventStreamStop(fsevent_stream_);
268 FSEventStreamInvalidate(fsevent_stream_); 269 FSEventStreamInvalidate(fsevent_stream_);
269 FSEventStreamRelease(fsevent_stream_); 270 FSEventStreamRelease(fsevent_stream_);
270 fsevent_stream_ = NULL; 271 fsevent_stream_ = NULL;
271 } 272 }
272 273
273 void FilePathWatcherFSEvents::StartEventStream(FSEventStreamEventId start_event, 274 void FilePathWatcherFSEvents::StartEventStream(FSEventStreamEventId start_event,
274 const FilePath& path) { 275 const FilePath& path) {
275 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread()); 276 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread());
276 DCHECK(resolved_target_.empty()); 277 DCHECK(resolved_target_.empty());
277 278
278 target_ = path; 279 target_ = path;
279 ResolveTargetPath(); 280 ResolveTargetPath();
280 UpdateEventStream(start_event); 281 UpdateEventStream(start_event);
281 } 282 }
282 283
283 } // namespace base 284 } // namespace base
OLDNEW
« no previous file with comments | « base/files/file_path_watcher.h ('k') | base/files/file_path_watcher_kqueue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698