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

Unified Diff: runtime/bin/file_system_watcher_macos.cc

Issue 147083015: Fix file-watcher on mac by always starting/stopping through the run-loop thread. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/file_system_watcher_macos.cc
diff --git a/runtime/bin/file_system_watcher_macos.cc b/runtime/bin/file_system_watcher_macos.cc
index 678f45f20b59b025ba4975f50297bfecbd063638..8669d7234ae261811639dd6cfac7910c666b7130 100644
--- a/runtime/bin/file_system_watcher_macos.cc
+++ b/runtime/bin/file_system_watcher_macos.cc
@@ -55,37 +55,86 @@ class FSEventsWatcher {
public:
class Node {
public:
- Node(intptr_t base_path_length, int read_fd, int write_fd, bool recursive)
- : base_path_length_(base_path_length),
- read_fd_(read_fd),
- write_fd_(write_fd),
- recursive_(recursive),
- ref_(NULL) {}
+ Node(FSEventsWatcher* watcher, intptr_t base_path_length, int read_fd,
+ int write_fd, bool recursive)
+ : watcher_(watcher),
+ ready_(false),
Søren Gjesse 2014/02/06 13:04:19 Indent
Anders Johnsen 2014/02/06 13:15:22 Done.
+ base_path_length_(base_path_length),
+ read_fd_(read_fd),
+ write_fd_(write_fd),
+ recursive_(recursive),
+ ref_(NULL) {}
~Node() {
close(write_fd_);
- FSEventStreamInvalidate(ref_);
- FSEventStreamRelease(ref_);
}
void set_ref(FSEventStreamRef ref) {
ref_ = ref;
}
+ static void StartCallback(CFRunLoopTimerRef timer, void* info) {
+ Node* node = reinterpret_cast<Node*>(info);
+ FSEventStreamScheduleWithRunLoop(
+ node->ref_,
+ node->watcher_->run_loop_,
+ kCFRunLoopDefaultMode);
+ FSEventStreamStart(node->ref_);
+ FSEventStreamFlushSync(node->ref_);
+ node->watcher_->monitor_.Enter();
+ node->ready_ = true;
+ node->watcher_->monitor_.Notify();
+ node->watcher_->monitor_.Exit();
+ }
+
void Start() {
Søren Gjesse 2014/02/06 13:04:19 ASSERT(!ready_)
Anders Johnsen 2014/02/06 13:15:22 Done.
- FSEventStreamStart(ref_);
+ CFRunLoopTimerContext context;
+ memset(&context, 0, sizeof(context));
+ context.info = this;
+ CFRunLoopTimerRef timer = CFRunLoopTimerCreate(
+ NULL, 0, 0, 0, 0, StartCallback, &context);
+ CFRunLoopAddTimer(watcher_->run_loop_, timer, kCFRunLoopCommonModes);
+ watcher_->monitor_.Enter();
+ while (!ready_) {
+ watcher_->monitor_.Wait(Monitor::kNoTimeout);
+ }
+ watcher_->monitor_.Exit();
+ }
+
+ static void StopCallback(CFRunLoopTimerRef timer, void* info) {
+ Node* node = reinterpret_cast<Node*>(info);
+ FSEventStreamStop(node->ref_);
+ FSEventStreamInvalidate(node->ref_);
+ FSEventStreamRelease(node->ref_);
+ node->watcher_->monitor_.Enter();
+ node->ready_ = false;
+ node->watcher_->monitor_.Notify();
+ node->watcher_->monitor_.Exit();
}
void Stop() {
Søren Gjesse 2014/02/06 13:04:19 ASSERT(ready_)
Anders Johnsen 2014/02/06 13:15:22 Done.
- FSEventStreamStop(ref_);
+ CFRunLoopTimerContext context;
+ memset(&context, 0, sizeof(context));
+ context.info = this;
+ CFRunLoopTimerRef timer = CFRunLoopTimerCreate(
+ NULL, 0, 0, 0, 0, StopCallback, &context);
+ CFRunLoopAddTimer(watcher_->run_loop_, timer, kCFRunLoopCommonModes);
+ watcher_->monitor_.Enter();
+ while (ready_) {
+ watcher_->monitor_.Wait(Monitor::kNoTimeout);
+ }
+ watcher_->monitor_.Exit();
}
+ bool ready() const { return ready_; }
intptr_t base_path_length() const { return base_path_length_; }
int read_fd() const { return read_fd_; }
int write_fd() const { return write_fd_; }
bool recursive() const { return recursive_; }
private:
+ FSEventsWatcher* watcher_;
+ bool ready_;
intptr_t base_path_length_;
int read_fd_;
int write_fd_;
@@ -143,7 +192,7 @@ class FSEventsWatcher {
CFStringRef path_ref = CFStringCreateWithCString(
NULL, base_path, kCFStringEncodingUTF8);
- Node* node = new Node(strlen(base_path), fds[0], fds[1], recursive);
+ Node* node = new Node(this, strlen(base_path), fds[0], fds[1], recursive);
FSEventStreamContext context;
context.version = 0;
@@ -162,11 +211,6 @@ class FSEventsWatcher {
node->set_ref(ref);
- FSEventStreamScheduleWithRunLoop(
- ref,
- run_loop_,
- kCFRunLoopDefaultMode);
-
return node;
}
@@ -178,6 +222,7 @@ class FSEventsWatcher {
const FSEventStreamEventFlags event_flags[],
const FSEventStreamEventId event_ids[]) {
Node* node = reinterpret_cast<Node*>(client);
Søren Gjesse 2014/02/06 13:04:19 Need to protect access to ready with the monitor.
Anders Johnsen 2014/02/06 13:15:22 As discussed offline, is on same thread as run-loo
+ if (!node->ready()) return;
for (size_t i = 0; i < num_events; i++) {
char *path = reinterpret_cast<char**>(event_paths)[i];
FSEvent event;
@@ -207,7 +252,7 @@ intptr_t FileSystemWatcher::Init() {
FSEventsWatcher* watcher = new FSEventsWatcher();
watcher->monitor().Enter();
while (!watcher->has_run_loop()) {
- watcher->monitor().Wait(1);
+ watcher->monitor().Wait(Monitor::kNoTimeout);
}
watcher->monitor().Exit();
return reinterpret_cast<intptr_t>(watcher);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698