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 2200b78c014d0ada6fe5cad4bed10be65d7265e1..c524e36f42b5db1a3a1fae5eadcd3310d7f2d09a 100644 |
--- a/runtime/bin/file_system_watcher_macos.cc |
+++ b/runtime/bin/file_system_watcher_macos.cc |
@@ -42,12 +42,6 @@ enum { |
namespace dart { |
namespace bin { |
-static Mutex* watcher_mutex = new Mutex(); |
-static Monitor* watcher_monitor = new Monitor(); |
- |
-class FSEventsWatcher; |
-static FSEventsWatcher* watcher = NULL; |
- |
union FSEvent { |
struct { |
uint32_t exists; |
@@ -99,7 +93,7 @@ class FSEventsWatcher { |
FSEventStreamRef ref_; |
}; |
- FSEventsWatcher() : run_loop_(0), users_(0) { |
+ FSEventsWatcher() : run_loop_(0) { |
Thread::Start(Run, reinterpret_cast<uword>(this)); |
} |
@@ -107,6 +101,10 @@ class FSEventsWatcher { |
CFRunLoopStop(run_loop_); |
} |
+ Monitor& monitor() { return monitor_; } |
+ |
+ bool has_run_loop() const { return run_loop_ != NULL; } |
+ |
static void TimerCallback(CFRunLoopTimerRef timer, void* context) { |
// Dummy callback to keep RunLoop alive. |
} |
@@ -116,9 +114,9 @@ class FSEventsWatcher { |
watcher->run_loop_ = CFRunLoopGetCurrent(); |
// Notify, as the run-loop is set. |
- watcher_monitor->Enter(); |
- watcher_monitor->Notify(); |
- watcher_monitor->Exit(); |
+ watcher->monitor().Enter(); |
+ watcher->monitor().Notify(); |
+ watcher->monitor().Exit(); |
CFRunLoopTimerRef timer = CFRunLoopTimerCreate( |
NULL, |
@@ -134,27 +132,6 @@ class FSEventsWatcher { |
CFRunLoopRun(); |
} |
- static void Increment() { |
- if (watcher == NULL) { |
- watcher_monitor->Enter(); |
- watcher = new FSEventsWatcher(); |
- while (watcher->run_loop_ == NULL) { |
- watcher_monitor->Wait(Monitor::kNoTimeout); |
- } |
- watcher_monitor->Exit(); |
- } |
- watcher->users_++; |
- } |
- |
- static void Decrement() { |
- ASSERT(watcher->users_ > 0); |
- watcher->users_--; |
- if (watcher->users_ == 0) { |
- delete watcher; |
- watcher = NULL; |
- } |
- } |
- |
Node* AddPath(const char* path, int events, bool recursive) { |
int fds[2]; |
VOID_TEMP_FAILURE_RETRY(pipe(fds)); |
@@ -215,8 +192,8 @@ class FSEventsWatcher { |
} |
} |
+ Monitor monitor_; |
CFRunLoopRef run_loop_; |
- int users_; |
}; |
@@ -226,36 +203,50 @@ bool FileSystemWatcher::IsSupported() { |
} |
-intptr_t FileSystemWatcher::WatchPath(const char* path, |
+intptr_t FileSystemWatcher::Init() { |
+ FSEventsWatcher* watcher = new FSEventsWatcher(); |
+ watcher->monitor().Enter(); |
+ while (!watcher->has_run_loop()) { |
+ watcher->monitor().Wait(1); |
+ } |
+ watcher->monitor().Exit(); |
+ return reinterpret_cast<intptr_t>(watcher); |
+} |
+ |
+ |
+void FileSystemWatcher::Close(intptr_t id) { |
+ FSEventsWatcher* watcher = reinterpret_cast<FSEventsWatcher*>(id); |
+ delete watcher; |
+} |
+ |
+ |
+intptr_t FileSystemWatcher::WatchPath(intptr_t id, |
+ const char* path, |
int events, |
bool recursive) { |
- MutexLocker lock(watcher_mutex); |
- FSEventsWatcher::Increment(); |
- |
+ FSEventsWatcher* watcher = reinterpret_cast<FSEventsWatcher*>(id); |
FSEventsWatcher::Node* node = watcher->AddPath(path, events, recursive); |
node->Start(); |
return reinterpret_cast<intptr_t>(node); |
} |
-void FileSystemWatcher::UnwatchPath(intptr_t id) { |
- MutexLocker lock(watcher_mutex); |
- |
- FSEventsWatcher::Node* node = reinterpret_cast<FSEventsWatcher::Node*>(id); |
+void FileSystemWatcher::UnwatchPath(intptr_t id, intptr_t path_id) { |
+ USE(id); |
+ FSEventsWatcher::Node* node = |
+ reinterpret_cast<FSEventsWatcher::Node*>(path_id); |
node->Stop(); |
delete node; |
- |
- FSEventsWatcher::Decrement(); |
} |
-intptr_t FileSystemWatcher::GetSocketId(intptr_t id) { |
- return reinterpret_cast<FSEventsWatcher::Node*>(id)->read_fd(); |
+intptr_t FileSystemWatcher::GetSocketId(intptr_t id, intptr_t path_id) { |
+ return reinterpret_cast<FSEventsWatcher::Node*>(path_id)->read_fd(); |
} |
-Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id) { |
- intptr_t fd = GetSocketId(id); |
+Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id, intptr_t path_id) { |
+ intptr_t fd = GetSocketId(id, path_id); |
intptr_t avail = FDUtils::AvailableBytes(fd); |
int count = avail / sizeof(FSEvent); |
if (count <= 0) return Dart_NewList(0); |
@@ -267,7 +258,7 @@ Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id) { |
return DartUtils::NewDartOSError(); |
} |
size_t path_len = strlen(e.data.path); |
- Dart_Handle event = Dart_NewList(4); |
+ Dart_Handle event = Dart_NewList(5); |
int flags = e.data.flags; |
int mask = 0; |
if (flags & kFSEventStreamEventFlagItemRenamed) { |
@@ -295,6 +286,7 @@ Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id) { |
Dart_ListSetAt(event, 2, Dart_NewStringFromUTF8( |
reinterpret_cast<uint8_t*>(e.data.path), path_len)); |
Dart_ListSetAt(event, 3, Dart_NewBoolean(true)); |
+ Dart_ListSetAt(event, 4, Dart_NewInteger(path_id)); |
Dart_ListSetAt(events, i, event); |
} |
return events; |