| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_MACOS) | 6 #if defined(TARGET_OS_MACOS) |
| 7 | 7 |
| 8 #include "bin/file_system_watcher.h" | 8 #include "bin/file_system_watcher.h" |
| 9 | 9 |
| 10 #include <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
| 11 #include <fcntl.h> // NOLINT | 11 #include <fcntl.h> // NOLINT |
| 12 #include <unistd.h> // NOLINT | 12 #include <unistd.h> // NOLINT |
| 13 #include <CoreServices/CoreServices.h> // NOLINT | 13 #include <CoreServices/CoreServices.h> // NOLINT |
| 14 | 14 |
| 15 #include "bin/eventhandler.h" | 15 #include "bin/eventhandler.h" |
| 16 #include "bin/fdutils.h" | 16 #include "bin/fdutils.h" |
| 17 #include "bin/file.h" |
| 17 #include "bin/socket.h" | 18 #include "bin/socket.h" |
| 18 #include "bin/thread.h" | 19 #include "bin/thread.h" |
| 19 | 20 |
| 20 | 21 |
| 21 #ifndef MAC_OS_X_VERSION_10_7 | 22 #ifndef MAC_OS_X_VERSION_10_7 |
| 22 enum { | 23 enum { |
| 23 kFSEventStreamCreateFlagFileEvents = 0x00000010 | 24 kFSEventStreamCreateFlagFileEvents = 0x00000010 |
| 24 }; | 25 }; |
| 25 enum { | 26 enum { |
| 26 kFSEventStreamEventFlagItemCreated = 0x00000100, | 27 kFSEventStreamEventFlagItemCreated = 0x00000100, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 42 namespace bin { | 43 namespace bin { |
| 43 | 44 |
| 44 static Mutex* watcher_mutex = new Mutex(); | 45 static Mutex* watcher_mutex = new Mutex(); |
| 45 static Monitor* watcher_monitor = new Monitor(); | 46 static Monitor* watcher_monitor = new Monitor(); |
| 46 | 47 |
| 47 class FSEventsWatcher; | 48 class FSEventsWatcher; |
| 48 static FSEventsWatcher* watcher = NULL; | 49 static FSEventsWatcher* watcher = NULL; |
| 49 | 50 |
| 50 union FSEvent { | 51 union FSEvent { |
| 51 struct { | 52 struct { |
| 53 uint32_t exists; |
| 52 uint32_t flags; | 54 uint32_t flags; |
| 53 char path[PATH_MAX]; | 55 char path[PATH_MAX]; |
| 54 } data; | 56 } data; |
| 55 uint8_t bytes[PATH_MAX + 4]; | 57 uint8_t bytes[PATH_MAX + 8]; |
| 56 }; | 58 }; |
| 57 | 59 |
| 58 class FSEventsWatcher { | 60 class FSEventsWatcher { |
| 59 public: | 61 public: |
| 60 class Node { | 62 class Node { |
| 61 public: | 63 public: |
| 62 Node(intptr_t base_path_length, int read_fd, int write_fd, bool recursive) | 64 Node(intptr_t base_path_length, int read_fd, int write_fd, bool recursive) |
| 63 : base_path_length_(base_path_length), | 65 : base_path_length_(base_path_length), |
| 64 read_fd_(read_fd), | 66 read_fd_(read_fd), |
| 65 write_fd_(write_fd), | 67 write_fd_(write_fd), |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 context.retain = NULL; | 174 context.retain = NULL; |
| 173 context.release = NULL; | 175 context.release = NULL; |
| 174 context.copyDescription = NULL; | 176 context.copyDescription = NULL; |
| 175 FSEventStreamRef ref = FSEventStreamCreate( | 177 FSEventStreamRef ref = FSEventStreamCreate( |
| 176 NULL, | 178 NULL, |
| 177 Callback, | 179 Callback, |
| 178 &context, | 180 &context, |
| 179 CFArrayCreate(NULL, reinterpret_cast<const void**>(&path_ref), 1, NULL), | 181 CFArrayCreate(NULL, reinterpret_cast<const void**>(&path_ref), 1, NULL), |
| 180 kFSEventStreamEventIdSinceNow, | 182 kFSEventStreamEventIdSinceNow, |
| 181 0.10, | 183 0.10, |
| 182 kFSEventStreamCreateFlagFileEvents); | 184 kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents); |
| 183 | 185 |
| 184 node->set_ref(ref); | 186 node->set_ref(ref); |
| 185 | 187 |
| 186 FSEventStreamScheduleWithRunLoop( | 188 FSEventStreamScheduleWithRunLoop( |
| 187 ref, | 189 ref, |
| 188 run_loop_, | 190 run_loop_, |
| 189 kCFRunLoopDefaultMode); | 191 kCFRunLoopDefaultMode); |
| 190 | 192 |
| 191 return node; | 193 return node; |
| 192 } | 194 } |
| 193 | 195 |
| 194 private: | 196 private: |
| 195 static void Callback(ConstFSEventStreamRef ref, | 197 static void Callback(ConstFSEventStreamRef ref, |
| 196 void* client, | 198 void* client, |
| 197 size_t num_events, | 199 size_t num_events, |
| 198 void* event_paths, | 200 void* event_paths, |
| 199 const FSEventStreamEventFlags event_flags[], | 201 const FSEventStreamEventFlags event_flags[], |
| 200 const FSEventStreamEventId event_ids[]) { | 202 const FSEventStreamEventId event_ids[]) { |
| 201 Node* node = reinterpret_cast<Node*>(client); | 203 Node* node = reinterpret_cast<Node*>(client); |
| 202 for (size_t i = 0; i < num_events; i++) { | 204 for (size_t i = 0; i < num_events; i++) { |
| 203 char *path = reinterpret_cast<char**>(event_paths)[i]; | 205 char *path = reinterpret_cast<char**>(event_paths)[i]; |
| 206 FSEvent event; |
| 207 event.data.exists = File::Exists(path); |
| 204 path += node->base_path_length(); | 208 path += node->base_path_length(); |
| 205 // If path is longer the base, skip next character ('/'). | 209 // If path is longer the base, skip next character ('/'). |
| 206 if (path[0] != '\0') path += 1; | 210 if (path[0] != '\0') path += 1; |
| 207 if (!node->recursive() && strstr(path, "/") != NULL) continue; | 211 if (!node->recursive() && strstr(path, "/") != NULL) continue; |
| 208 FSEvent event; | |
| 209 event.data.flags = event_flags[i]; | 212 event.data.flags = event_flags[i]; |
| 210 memmove(event.data.path, path, strlen(path) + 1); | 213 memmove(event.data.path, path, strlen(path) + 1); |
| 211 write(node->write_fd(), event.bytes, sizeof(event)); | 214 write(node->write_fd(), event.bytes, sizeof(event)); |
| 212 } | 215 } |
| 213 } | 216 } |
| 214 | 217 |
| 215 CFRunLoopRef run_loop_; | 218 CFRunLoopRef run_loop_; |
| 216 int users_; | 219 int users_; |
| 217 }; | 220 }; |
| 218 | 221 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 } | 268 } |
| 266 size_t path_len = strlen(e.data.path); | 269 size_t path_len = strlen(e.data.path); |
| 267 Dart_Handle event = Dart_NewList(4); | 270 Dart_Handle event = Dart_NewList(4); |
| 268 int flags = e.data.flags; | 271 int flags = e.data.flags; |
| 269 int mask = 0; | 272 int mask = 0; |
| 270 if (flags & kFSEventStreamEventFlagItemRenamed) { | 273 if (flags & kFSEventStreamEventFlagItemRenamed) { |
| 271 if (path_len == 0) { | 274 if (path_len == 0) { |
| 272 // The moved path is the path being watched. | 275 // The moved path is the path being watched. |
| 273 mask |= kDeleteSelf; | 276 mask |= kDeleteSelf; |
| 274 } else { | 277 } else { |
| 275 mask |= kMove; | 278 mask |= e.data.exists ? kCreate : kDelete; |
| 276 } | 279 } |
| 277 } | 280 } |
| 278 if (flags & kFSEventStreamEventFlagItemModified) mask |= kModifyContent; | 281 if (flags & kFSEventStreamEventFlagItemModified) mask |= kModifyContent; |
| 279 if (flags & kFSEventStreamEventFlagItemXattrMod) mask |= kModefyAttribute; | 282 if (flags & kFSEventStreamEventFlagItemXattrMod) mask |= kModefyAttribute; |
| 280 if (flags & kFSEventStreamEventFlagItemCreated) mask |= kCreate; | 283 if (flags & kFSEventStreamEventFlagItemCreated) mask |= kCreate; |
| 281 if (flags & kFSEventStreamEventFlagItemIsDir) mask |= kIsDir; | 284 if (flags & kFSEventStreamEventFlagItemIsDir) mask |= kIsDir; |
| 282 if (flags & kFSEventStreamEventFlagItemRemoved) { | 285 if (flags & kFSEventStreamEventFlagItemRemoved) { |
| 283 if (path_len == 0) { | 286 if (path_len == 0) { |
| 284 // The removed path is the path being watched. | 287 // The removed path is the path being watched. |
| 285 mask |= kDeleteSelf; | 288 mask |= kDeleteSelf; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 296 } | 299 } |
| 297 return events; | 300 return events; |
| 298 } | 301 } |
| 299 | 302 |
| 300 } // namespace bin | 303 } // namespace bin |
| 301 } // namespace dart | 304 } // namespace dart |
| 302 | 305 |
| 303 #endif // defined(TARGET_OS_MACOS) | 306 #endif // defined(TARGET_OS_MACOS) |
| 304 | 307 |
| 305 | 308 |
| OLD | NEW |