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

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

Issue 369703003: Reduce usage of MessageLoopProxy in base/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 6 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 | Annotate | Revision Log
« no previous file with comments | « base/files/file_path_watcher_browsertest.cc ('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/sequenced_task_runner.h"
17 #include "base/thread_task_runner_handle.h"
16 18
17 namespace base { 19 namespace base {
18 20
19 namespace { 21 namespace {
20 22
21 // The latency parameter passed to FSEventsStreamCreate(). 23 // The latency parameter passed to FSEventsStreamCreate().
22 const CFAbsoluteTime kEventLatencySeconds = 0.3; 24 const CFAbsoluteTime kEventLatencySeconds = 0.3;
23 25
24 class FSEventsTaskRunner : public mac::LibDispatchTaskRunner { 26 class FSEventsTaskRunner : public mac::LibDispatchTaskRunner {
25 public: 27 public:
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 watcher->OnFilePathsChanged(paths); 113 watcher->OnFilePathsChanged(paths);
112 } 114 }
113 115
114 } // namespace 116 } // namespace
115 117
116 FilePathWatcherFSEvents::FilePathWatcherFSEvents() : fsevent_stream_(NULL) { 118 FilePathWatcherFSEvents::FilePathWatcherFSEvents() : fsevent_stream_(NULL) {
117 } 119 }
118 120
119 void FilePathWatcherFSEvents::OnFilePathsChanged( 121 void FilePathWatcherFSEvents::OnFilePathsChanged(
120 const std::vector<FilePath>& paths) { 122 const std::vector<FilePath>& paths) {
121 if (!message_loop()->BelongsToCurrentThread()) { 123 if (!task_runner()->RunsTasksOnCurrentThread()) {
122 message_loop()->PostTask( 124 task_runner()->PostTask(
123 FROM_HERE, 125 FROM_HERE,
124 Bind(&FilePathWatcherFSEvents::OnFilePathsChanged, this, paths)); 126 Bind(&FilePathWatcherFSEvents::OnFilePathsChanged, this, paths));
125 return; 127 return;
126 } 128 }
127 129
128 DCHECK(message_loop()->BelongsToCurrentThread()); 130 DCHECK(task_runner()->RunsTasksOnCurrentThread());
129 if (resolved_target_.empty()) 131 if (resolved_target_.empty())
130 return; 132 return;
131 133
132 for (size_t i = 0; i < paths.size(); i++) { 134 for (size_t i = 0; i < paths.size(); i++) {
133 if (resolved_target_.IsParent(paths[i]) || resolved_target_ == paths[i]) { 135 if (resolved_target_.IsParent(paths[i]) || resolved_target_ == paths[i]) {
134 callback_.Run(target_, false); 136 callback_.Run(target_, false);
135 return; 137 return;
136 } 138 }
137 } 139 }
138 } 140 }
139 141
140 bool FilePathWatcherFSEvents::Watch(const FilePath& path, 142 bool FilePathWatcherFSEvents::Watch(const FilePath& path,
141 bool recursive, 143 bool recursive,
142 const FilePathWatcher::Callback& callback) { 144 const FilePathWatcher::Callback& callback) {
143 DCHECK(resolved_target_.empty()); 145 DCHECK(resolved_target_.empty());
144 DCHECK(MessageLoopForIO::current()); 146 DCHECK(MessageLoopForIO::current());
145 DCHECK(!callback.is_null()); 147 DCHECK(!callback.is_null());
146 148
147 // This class could support non-recursive watches, but that is currently 149 // This class could support non-recursive watches, but that is currently
148 // left to FilePathWatcherKQueue. 150 // left to FilePathWatcherKQueue.
149 if (!recursive) 151 if (!recursive)
150 return false; 152 return false;
151 153
152 set_message_loop(MessageLoopProxy::current()); 154 set_task_runner(ThreadTaskRunnerHandle::Get());
153 callback_ = callback; 155 callback_ = callback;
154 target_ = path; 156 target_ = path;
155 157
156 FSEventStreamEventId start_event = FSEventsGetCurrentEventId(); 158 FSEventStreamEventId start_event = FSEventsGetCurrentEventId();
157 g_task_runner.Get().PostTask( 159 g_task_runner.Get().PostTask(
158 FROM_HERE, 160 FROM_HERE,
159 Bind(&FilePathWatcherFSEvents::StartEventStream, this, start_event)); 161 Bind(&FilePathWatcherFSEvents::StartEventStream, this, start_event));
160 return true; 162 return true;
161 } 163 }
162 164
(...skipping 10 matching lines...) Expand all
173 g_task_runner.Get().PostTask( 175 g_task_runner.Get().PostTask(
174 FROM_HERE, 176 FROM_HERE,
175 Bind(&FilePathWatcherFSEvents::CancelOnMessageLoopThread, this)); 177 Bind(&FilePathWatcherFSEvents::CancelOnMessageLoopThread, this));
176 } else { 178 } else {
177 CancelOnMessageLoopThread(); 179 CancelOnMessageLoopThread();
178 } 180 }
179 } 181 }
180 182
181 void FilePathWatcherFSEvents::CancelOnMessageLoopThread() { 183 void FilePathWatcherFSEvents::CancelOnMessageLoopThread() {
182 // For all other implementations, the "message loop thread" is the IO thread, 184 // For all other implementations, the "message loop thread" is the IO thread,
183 // as returned by message_loop(). This implementation, however, needs to 185 // as returned by task_runner(). This implementation, however, needs to
184 // cancel pending work on the Dipatch Queue thread. 186 // cancel pending work on the Dipatch Queue thread.
185 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread()); 187 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread());
186 188
187 set_cancelled(); 189 set_cancelled();
188 if (fsevent_stream_) { 190 if (fsevent_stream_) {
189 DestroyEventStream(); 191 DestroyEventStream();
190 callback_.Reset(); 192 callback_.Reset();
191 target_.clear(); 193 target_.clear();
192 resolved_target_.clear(); 194 resolved_target_.clear();
193 } 195 }
(...skipping 30 matching lines...) Expand all
224 226
225 fsevent_stream_ = FSEventStreamCreate(NULL, &FSEventsCallback, &context, 227 fsevent_stream_ = FSEventStreamCreate(NULL, &FSEventsCallback, &context,
226 watched_paths, 228 watched_paths,
227 start_event, 229 start_event,
228 kEventLatencySeconds, 230 kEventLatencySeconds,
229 kFSEventStreamCreateFlagWatchRoot); 231 kFSEventStreamCreateFlagWatchRoot);
230 FSEventStreamSetDispatchQueue(fsevent_stream_, 232 FSEventStreamSetDispatchQueue(fsevent_stream_,
231 g_task_runner.Get().GetDispatchQueue()); 233 g_task_runner.Get().GetDispatchQueue());
232 234
233 if (!FSEventStreamStart(fsevent_stream_)) 235 if (!FSEventStreamStart(fsevent_stream_))
234 message_loop()->PostTask(FROM_HERE, Bind(callback_, target_, true)); 236 task_runner()->PostTask(FROM_HERE, Bind(callback_, target_, true));
235 } 237 }
236 238
237 bool FilePathWatcherFSEvents::ResolveTargetPath() { 239 bool FilePathWatcherFSEvents::ResolveTargetPath() {
238 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread()); 240 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread());
239 FilePath resolved = ResolvePath(target_).StripTrailingSeparators(); 241 FilePath resolved = ResolvePath(target_).StripTrailingSeparators();
240 bool changed = resolved != resolved_target_; 242 bool changed = resolved != resolved_target_;
241 resolved_target_ = resolved; 243 resolved_target_ = resolved;
242 if (resolved_target_.empty()) 244 if (resolved_target_.empty())
243 message_loop()->PostTask(FROM_HERE, Bind(callback_, target_, true)); 245 task_runner()->PostTask(FROM_HERE, Bind(callback_, target_, true));
244 return changed; 246 return changed;
245 } 247 }
246 248
247 void FilePathWatcherFSEvents::DestroyEventStream() { 249 void FilePathWatcherFSEvents::DestroyEventStream() {
248 FSEventStreamStop(fsevent_stream_); 250 FSEventStreamStop(fsevent_stream_);
249 FSEventStreamInvalidate(fsevent_stream_); 251 FSEventStreamInvalidate(fsevent_stream_);
250 FSEventStreamRelease(fsevent_stream_); 252 FSEventStreamRelease(fsevent_stream_);
251 fsevent_stream_ = NULL; 253 fsevent_stream_ = NULL;
252 } 254 }
253 255
254 void FilePathWatcherFSEvents::StartEventStream( 256 void FilePathWatcherFSEvents::StartEventStream(
255 FSEventStreamEventId start_event) { 257 FSEventStreamEventId start_event) {
256 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread()); 258 DCHECK(g_task_runner.Get().RunsTasksOnCurrentThread());
257 ResolveTargetPath(); 259 ResolveTargetPath();
258 UpdateEventStream(start_event); 260 UpdateEventStream(start_event);
259 } 261 }
260 262
261 FilePathWatcherFSEvents::~FilePathWatcherFSEvents() {} 263 FilePathWatcherFSEvents::~FilePathWatcherFSEvents() {}
262 264
263 } // namespace base 265 } // namespace base
OLDNEW
« no previous file with comments | « base/files/file_path_watcher_browsertest.cc ('k') | base/files/file_path_watcher_kqueue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698