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

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