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 #if !defined(DART_IO_DISABLED) | 5 #if !defined(DART_IO_DISABLED) |
6 | 6 |
7 #include "platform/globals.h" | 7 #include "platform/globals.h" |
8 #if defined(TARGET_OS_MACOS) | 8 #if defined(TARGET_OS_MACOS) |
9 | 9 |
10 #include "bin/file_system_watcher.h" | 10 #include "bin/file_system_watcher.h" |
11 | 11 |
12 #if !TARGET_OS_IOS | 12 #if !TARGET_OS_IOS |
13 | 13 |
14 #include <errno.h> // NOLINT | 14 #include <errno.h> // NOLINT |
15 #include <fcntl.h> // NOLINT | 15 #include <fcntl.h> // NOLINT |
16 #include <unistd.h> // NOLINT | 16 #include <unistd.h> // NOLINT |
17 #include <CoreServices/CoreServices.h> // NOLINT | 17 #include <CoreServices/CoreServices.h> // NOLINT |
18 | 18 |
19 #include "bin/eventhandler.h" | 19 #include "bin/eventhandler.h" |
20 #include "bin/fdutils.h" | 20 #include "bin/fdutils.h" |
21 #include "bin/file.h" | 21 #include "bin/file.h" |
22 #include "bin/socket.h" | 22 #include "bin/socket.h" |
23 #include "bin/thread.h" | 23 #include "bin/thread.h" |
24 #include "platform/signal_blocker.h" | 24 #include "platform/signal_blocker.h" |
25 | 25 |
26 #ifndef MAC_OS_X_VERSION_10_7 | 26 #ifndef MAC_OS_X_VERSION_10_7 |
27 enum { | 27 enum { kFSEventStreamCreateFlagFileEvents = 0x00000010 }; |
28 kFSEventStreamCreateFlagFileEvents = 0x00000010 | |
29 }; | |
30 enum { | 28 enum { |
31 kFSEventStreamEventFlagItemCreated = 0x00000100, | 29 kFSEventStreamEventFlagItemCreated = 0x00000100, |
32 kFSEventStreamEventFlagItemRemoved = 0x00000200, | 30 kFSEventStreamEventFlagItemRemoved = 0x00000200, |
33 kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400, | 31 kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400, |
34 kFSEventStreamEventFlagItemRenamed = 0x00000800, | 32 kFSEventStreamEventFlagItemRenamed = 0x00000800, |
35 kFSEventStreamEventFlagItemModified = 0x00001000, | 33 kFSEventStreamEventFlagItemModified = 0x00001000, |
36 kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000, | 34 kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000, |
37 kFSEventStreamEventFlagItemChangeOwner = 0x00004000, | 35 kFSEventStreamEventFlagItemChangeOwner = 0x00004000, |
38 kFSEventStreamEventFlagItemXattrMod = 0x00008000, | 36 kFSEventStreamEventFlagItemXattrMod = 0x00008000, |
39 kFSEventStreamEventFlagItemIsFile = 0x00010000, | 37 kFSEventStreamEventFlagItemIsFile = 0x00010000, |
(...skipping 12 matching lines...) Expand all Loading... |
52 char path[PATH_MAX]; | 50 char path[PATH_MAX]; |
53 } data; | 51 } data; |
54 uint8_t bytes[PATH_MAX + 8]; | 52 uint8_t bytes[PATH_MAX + 8]; |
55 }; | 53 }; |
56 | 54 |
57 | 55 |
58 class FSEventsWatcher { | 56 class FSEventsWatcher { |
59 public: | 57 public: |
60 class Node { | 58 class Node { |
61 public: | 59 public: |
62 Node(FSEventsWatcher* watcher, char* base_path, int read_fd, | 60 Node(FSEventsWatcher* watcher, |
63 int write_fd, bool recursive) | 61 char* base_path, |
| 62 int read_fd, |
| 63 int write_fd, |
| 64 bool recursive) |
64 : watcher_(watcher), | 65 : watcher_(watcher), |
65 ready_(false), | 66 ready_(false), |
66 base_path_length_(strlen(base_path)), | 67 base_path_length_(strlen(base_path)), |
67 path_ref_(CFStringCreateWithCString( | 68 path_ref_(CFStringCreateWithCString(NULL, |
68 NULL, base_path, kCFStringEncodingUTF8)), | 69 base_path, |
| 70 kCFStringEncodingUTF8)), |
69 read_fd_(read_fd), | 71 read_fd_(read_fd), |
70 write_fd_(write_fd), | 72 write_fd_(write_fd), |
71 recursive_(recursive), | 73 recursive_(recursive), |
72 ref_(NULL) { | 74 ref_(NULL) { |
73 Start(); | 75 Start(); |
74 } | 76 } |
75 | 77 |
76 ~Node() { | 78 ~Node() { |
77 Stop(); | 79 Stop(); |
78 VOID_TEMP_FAILURE_RETRY(close(write_fd_)); | 80 VOID_TEMP_FAILURE_RETRY(close(write_fd_)); |
79 CFRelease(path_ref_); | 81 CFRelease(path_ref_); |
80 } | 82 } |
81 | 83 |
82 void set_ref(FSEventStreamRef ref) { | 84 void set_ref(FSEventStreamRef ref) { ref_ = ref; } |
83 ref_ = ref; | |
84 } | |
85 | 85 |
86 void Start() { | 86 void Start() { |
87 // Schedule StartCallback to be executed in the RunLoop. | 87 // Schedule StartCallback to be executed in the RunLoop. |
88 CFRunLoopTimerContext context; | 88 CFRunLoopTimerContext context; |
89 memset(&context, 0, sizeof(context)); | 89 memset(&context, 0, sizeof(context)); |
90 context.info = this; | 90 context.info = this; |
91 CFRunLoopTimerRef timer = CFRunLoopTimerCreate( | 91 CFRunLoopTimerRef timer = |
92 NULL, 0, 0, 0, 0, Node::StartCallback, &context); | 92 CFRunLoopTimerCreate(NULL, 0, 0, 0, 0, Node::StartCallback, &context); |
93 CFRunLoopAddTimer(watcher_->run_loop_, timer, kCFRunLoopCommonModes); | 93 CFRunLoopAddTimer(watcher_->run_loop_, timer, kCFRunLoopCommonModes); |
94 CFRelease(timer); | 94 CFRelease(timer); |
95 watcher_->monitor_.Enter(); | 95 watcher_->monitor_.Enter(); |
96 while (!ready_) { | 96 while (!ready_) { |
97 watcher_->monitor_.Wait(Monitor::kNoTimeout); | 97 watcher_->monitor_.Wait(Monitor::kNoTimeout); |
98 } | 98 } |
99 watcher_->monitor_.Exit(); | 99 watcher_->monitor_.Exit(); |
100 } | 100 } |
101 | 101 |
102 static void StartCallback(CFRunLoopTimerRef timer, void* info) { | 102 static void StartCallback(CFRunLoopTimerRef timer, void* info) { |
103 Node* node = reinterpret_cast<Node*>(info); | 103 Node* node = reinterpret_cast<Node*>(info); |
104 ASSERT(Thread::Compare(node->watcher_->threadId_, | 104 ASSERT(Thread::Compare(node->watcher_->threadId_, |
105 Thread::GetCurrentThreadId())); | 105 Thread::GetCurrentThreadId())); |
106 FSEventStreamContext context; | 106 FSEventStreamContext context; |
107 memset(&context, 0, sizeof(context)); | 107 memset(&context, 0, sizeof(context)); |
108 context.info = reinterpret_cast<void*>(node); | 108 context.info = reinterpret_cast<void*>(node); |
109 CFArrayRef array = CFArrayCreate( | 109 CFArrayRef array = CFArrayCreate( |
110 NULL, reinterpret_cast<const void**>(&node->path_ref_), 1, NULL); | 110 NULL, reinterpret_cast<const void**>(&node->path_ref_), 1, NULL); |
111 FSEventStreamRef ref = FSEventStreamCreate( | 111 FSEventStreamRef ref = FSEventStreamCreate( |
112 NULL, | 112 NULL, Callback, &context, array, kFSEventStreamEventIdSinceNow, 0.10, |
113 Callback, | |
114 &context, | |
115 array, | |
116 kFSEventStreamEventIdSinceNow, | |
117 0.10, | |
118 kFSEventStreamCreateFlagFileEvents); | 113 kFSEventStreamCreateFlagFileEvents); |
119 CFRelease(array); | 114 CFRelease(array); |
120 | 115 |
121 node->set_ref(ref); | 116 node->set_ref(ref); |
122 | 117 |
123 FSEventStreamScheduleWithRunLoop( | 118 FSEventStreamScheduleWithRunLoop(node->ref_, node->watcher_->run_loop_, |
124 node->ref_, | 119 kCFRunLoopDefaultMode); |
125 node->watcher_->run_loop_, | |
126 kCFRunLoopDefaultMode); | |
127 | 120 |
128 FSEventStreamStart(node->ref_); | 121 FSEventStreamStart(node->ref_); |
129 FSEventStreamFlushSync(node->ref_); | 122 FSEventStreamFlushSync(node->ref_); |
130 | 123 |
131 node->watcher_->monitor_.Enter(); | 124 node->watcher_->monitor_.Enter(); |
132 node->ready_ = true; | 125 node->ready_ = true; |
133 node->watcher_->monitor_.Notify(); | 126 node->watcher_->monitor_.Notify(); |
134 node->watcher_->monitor_.Exit(); | 127 node->watcher_->monitor_.Exit(); |
135 } | 128 } |
136 | 129 |
137 void Stop() { | 130 void Stop() { |
138 // Schedule StopCallback to be executed in the RunLoop. | 131 // Schedule StopCallback to be executed in the RunLoop. |
139 ASSERT(ready_); | 132 ASSERT(ready_); |
140 CFRunLoopTimerContext context; | 133 CFRunLoopTimerContext context; |
141 memset(&context, 0, sizeof(context)); | 134 memset(&context, 0, sizeof(context)); |
142 context.info = this; | 135 context.info = this; |
143 CFRunLoopTimerRef timer = CFRunLoopTimerCreate( | 136 CFRunLoopTimerRef timer = |
144 NULL, 0, 0, 0, 0, StopCallback, &context); | 137 CFRunLoopTimerCreate(NULL, 0, 0, 0, 0, StopCallback, &context); |
145 CFRunLoopAddTimer(watcher_->run_loop_, timer, kCFRunLoopCommonModes); | 138 CFRunLoopAddTimer(watcher_->run_loop_, timer, kCFRunLoopCommonModes); |
146 CFRelease(timer); | 139 CFRelease(timer); |
147 watcher_->monitor_.Enter(); | 140 watcher_->monitor_.Enter(); |
148 while (ready_) { | 141 while (ready_) { |
149 watcher_->monitor_.Wait(Monitor::kNoTimeout); | 142 watcher_->monitor_.Wait(Monitor::kNoTimeout); |
150 } | 143 } |
151 watcher_->monitor_.Exit(); | 144 watcher_->monitor_.Exit(); |
152 } | 145 } |
153 | 146 |
154 static void StopCallback(CFRunLoopTimerRef timer, void* info) { | 147 static void StopCallback(CFRunLoopTimerRef timer, void* info) { |
(...skipping 23 matching lines...) Expand all Loading... |
178 CFStringRef path_ref_; | 171 CFStringRef path_ref_; |
179 int read_fd_; | 172 int read_fd_; |
180 int write_fd_; | 173 int write_fd_; |
181 bool recursive_; | 174 bool recursive_; |
182 FSEventStreamRef ref_; | 175 FSEventStreamRef ref_; |
183 | 176 |
184 DISALLOW_COPY_AND_ASSIGN(Node); | 177 DISALLOW_COPY_AND_ASSIGN(Node); |
185 }; | 178 }; |
186 | 179 |
187 | 180 |
188 FSEventsWatcher() : run_loop_(0) { | 181 FSEventsWatcher() : run_loop_(0) { Start(); } |
189 Start(); | |
190 } | |
191 | 182 |
192 void Start() { | 183 void Start() { |
193 Thread::Start(Run, reinterpret_cast<uword>(this)); | 184 Thread::Start(Run, reinterpret_cast<uword>(this)); |
194 monitor_.Enter(); | 185 monitor_.Enter(); |
195 while (run_loop_ == NULL) { | 186 while (run_loop_ == NULL) { |
196 monitor_.Wait(Monitor::kNoTimeout); | 187 monitor_.Wait(Monitor::kNoTimeout); |
197 } | 188 } |
198 monitor_.Exit(); | 189 monitor_.Exit(); |
199 } | 190 } |
200 | 191 |
201 static void Run(uword arg) { | 192 static void Run(uword arg) { |
202 FSEventsWatcher* watcher = reinterpret_cast<FSEventsWatcher*>(arg); | 193 FSEventsWatcher* watcher = reinterpret_cast<FSEventsWatcher*>(arg); |
203 // Only checked in debug mode. | 194 // Only checked in debug mode. |
204 watcher->threadId_ = Thread::GetCurrentThreadId(); | 195 watcher->threadId_ = Thread::GetCurrentThreadId(); |
205 watcher->run_loop_ = CFRunLoopGetCurrent(); | 196 watcher->run_loop_ = CFRunLoopGetCurrent(); |
206 CFRetain(watcher->run_loop_); | 197 CFRetain(watcher->run_loop_); |
207 | 198 |
208 // Notify, as the run-loop is set. | 199 // Notify, as the run-loop is set. |
209 watcher->monitor().Enter(); | 200 watcher->monitor().Enter(); |
210 watcher->monitor().Notify(); | 201 watcher->monitor().Notify(); |
211 watcher->monitor().Exit(); | 202 watcher->monitor().Exit(); |
212 | 203 |
213 CFRunLoopTimerRef timer = CFRunLoopTimerCreate( | 204 CFRunLoopTimerRef timer = CFRunLoopTimerCreate( |
214 NULL, | 205 NULL, CFAbsoluteTimeGetCurrent() + 1, 1, 0, 0, TimerCallback, NULL); |
215 CFAbsoluteTimeGetCurrent() + 1, | |
216 1, | |
217 0, | |
218 0, | |
219 TimerCallback, | |
220 NULL); | |
221 CFRunLoopAddTimer(watcher->run_loop_, timer, kCFRunLoopCommonModes); | 206 CFRunLoopAddTimer(watcher->run_loop_, timer, kCFRunLoopCommonModes); |
222 CFRelease(timer); | 207 CFRelease(timer); |
223 | 208 |
224 CFRunLoopRun(); | 209 CFRunLoopRun(); |
225 | 210 |
226 CFRelease(watcher->run_loop_); | 211 CFRelease(watcher->run_loop_); |
227 watcher->monitor_.Enter(); | 212 watcher->monitor_.Enter(); |
228 watcher->run_loop_ = NULL; | 213 watcher->run_loop_ = NULL; |
229 watcher->monitor_.Notify(); | 214 watcher->monitor_.Notify(); |
230 watcher->monitor_.Exit(); | 215 watcher->monitor_.Exit(); |
231 } | 216 } |
232 | 217 |
233 void Stop() { | 218 void Stop() { |
234 // Schedule StopCallback to be executed in the RunLoop. | 219 // Schedule StopCallback to be executed in the RunLoop. |
235 CFRunLoopTimerContext context; | 220 CFRunLoopTimerContext context; |
236 memset(&context, 0, sizeof(context)); | 221 memset(&context, 0, sizeof(context)); |
237 context.info = this; | 222 context.info = this; |
238 CFRunLoopTimerRef timer = CFRunLoopTimerCreate( | 223 CFRunLoopTimerRef timer = |
239 NULL, 0, 0, 0, 0, StopCallback, &context); | 224 CFRunLoopTimerCreate(NULL, 0, 0, 0, 0, StopCallback, &context); |
240 CFRunLoopAddTimer(run_loop_, timer, kCFRunLoopCommonModes); | 225 CFRunLoopAddTimer(run_loop_, timer, kCFRunLoopCommonModes); |
241 CFRelease(timer); | 226 CFRelease(timer); |
242 monitor_.Enter(); | 227 monitor_.Enter(); |
243 while (run_loop_ != NULL) { | 228 while (run_loop_ != NULL) { |
244 monitor_.Wait(Monitor::kNoTimeout); | 229 monitor_.Wait(Monitor::kNoTimeout); |
245 } | 230 } |
246 monitor_.Exit(); | 231 monitor_.Exit(); |
247 } | 232 } |
248 | 233 |
249 static void StopCallback(CFRunLoopTimerRef timer, void* info) { | 234 static void StopCallback(CFRunLoopTimerRef timer, void* info) { |
250 FSEventsWatcher* watcher = reinterpret_cast<FSEventsWatcher*>(info); | 235 FSEventsWatcher* watcher = reinterpret_cast<FSEventsWatcher*>(info); |
251 ASSERT(Thread::Compare(watcher->threadId_, | 236 ASSERT(Thread::Compare(watcher->threadId_, Thread::GetCurrentThreadId())); |
252 Thread::GetCurrentThreadId())); | |
253 CFRunLoopStop(watcher->run_loop_); | 237 CFRunLoopStop(watcher->run_loop_); |
254 } | 238 } |
255 | 239 |
256 ~FSEventsWatcher() { | 240 ~FSEventsWatcher() { Stop(); } |
257 Stop(); | |
258 } | |
259 | 241 |
260 Monitor& monitor() { return monitor_; } | 242 Monitor& monitor() { return monitor_; } |
261 | 243 |
262 bool has_run_loop() const { return run_loop_ != NULL; } | 244 bool has_run_loop() const { return run_loop_ != NULL; } |
263 | 245 |
264 static void TimerCallback(CFRunLoopTimerRef timer, void* context) { | 246 static void TimerCallback(CFRunLoopTimerRef timer, void* context) { |
265 // Dummy callback to keep RunLoop alive. | 247 // Dummy callback to keep RunLoop alive. |
266 } | 248 } |
267 | 249 |
268 Node* AddPath(const char* path, int events, bool recursive) { | 250 Node* AddPath(const char* path, int events, bool recursive) { |
(...skipping 17 matching lines...) Expand all Loading... |
286 const FSEventStreamEventId event_ids[]) { | 268 const FSEventStreamEventId event_ids[]) { |
287 Node* node = reinterpret_cast<Node*>(client); | 269 Node* node = reinterpret_cast<Node*>(client); |
288 ASSERT(Thread::Compare(node->watcher()->threadId_, | 270 ASSERT(Thread::Compare(node->watcher()->threadId_, |
289 Thread::GetCurrentThreadId())); | 271 Thread::GetCurrentThreadId())); |
290 // `ready` is set on same thread as this callback is invoked, so we don't | 272 // `ready` is set on same thread as this callback is invoked, so we don't |
291 // need to lock here. | 273 // need to lock here. |
292 if (!node->ready()) { | 274 if (!node->ready()) { |
293 return; | 275 return; |
294 } | 276 } |
295 for (size_t i = 0; i < num_events; i++) { | 277 for (size_t i = 0; i < num_events; i++) { |
296 char *path = reinterpret_cast<char**>(event_paths)[i]; | 278 char* path = reinterpret_cast<char**>(event_paths)[i]; |
297 FSEvent event; | 279 FSEvent event; |
298 event.data.exists = File::GetType(path, false) != File::kDoesNotExist; | 280 event.data.exists = File::GetType(path, false) != File::kDoesNotExist; |
299 path += node->base_path_length(); | 281 path += node->base_path_length(); |
300 // If path is longer the base, skip next character ('/'). | 282 // If path is longer the base, skip next character ('/'). |
301 if (path[0] != '\0') { | 283 if (path[0] != '\0') { |
302 path += 1; | 284 path += 1; |
303 } | 285 } |
304 if (!node->recursive() && (strstr(path, "/") != NULL)) { | 286 if (!node->recursive() && (strstr(path, "/") != NULL)) { |
305 continue; | 287 continue; |
306 } | 288 } |
307 event.data.flags = event_flags[i]; | 289 event.data.flags = event_flags[i]; |
308 memmove(event.data.path, path, strlen(path) + 1); | 290 memmove(event.data.path, path, strlen(path) + 1); |
309 write(node->write_fd(), event.bytes, sizeof(event)); | 291 write(node->write_fd(), event.bytes, sizeof(event)); |
310 } | 292 } |
311 } | 293 } |
312 | 294 |
313 Monitor monitor_; | 295 Monitor monitor_; |
314 CFRunLoopRef run_loop_; | 296 CFRunLoopRef run_loop_; |
315 ThreadId threadId_; | 297 ThreadId threadId_; |
316 | 298 |
317 DISALLOW_COPY_AND_ASSIGN(FSEventsWatcher); | 299 DISALLOW_COPY_AND_ASSIGN(FSEventsWatcher); |
318 }; | 300 }; |
319 | 301 |
320 | 302 |
321 #define kCFCoreFoundationVersionNumber10_7 635.00 | 303 #define kCFCoreFoundationVersionNumber10_7 635.00 |
322 bool FileSystemWatcher::IsSupported() { | 304 bool FileSystemWatcher::IsSupported() { |
323 return kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber10_7; | 305 return kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber10_7; |
324 } | 306 } |
325 | 307 |
326 | 308 |
327 intptr_t FileSystemWatcher::Init() { | 309 intptr_t FileSystemWatcher::Init() { |
328 return reinterpret_cast<intptr_t>(new FSEventsWatcher()); | 310 return reinterpret_cast<intptr_t>(new FSEventsWatcher()); |
329 } | 311 } |
330 | 312 |
331 | 313 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 if ((flags & kFSEventStreamEventFlagItemRemoved) != 0) { | 377 if ((flags & kFSEventStreamEventFlagItemRemoved) != 0) { |
396 if (path_len == 0) { | 378 if (path_len == 0) { |
397 // The removed path is the path being watched. | 379 // The removed path is the path being watched. |
398 mask |= kDeleteSelf; | 380 mask |= kDeleteSelf; |
399 } else { | 381 } else { |
400 mask |= kDelete; | 382 mask |= kDelete; |
401 } | 383 } |
402 } | 384 } |
403 Dart_ListSetAt(event, 0, Dart_NewInteger(mask)); | 385 Dart_ListSetAt(event, 0, Dart_NewInteger(mask)); |
404 Dart_ListSetAt(event, 1, Dart_NewInteger(1)); | 386 Dart_ListSetAt(event, 1, Dart_NewInteger(1)); |
405 Dart_ListSetAt(event, 2, Dart_NewStringFromUTF8( | 387 Dart_ListSetAt(event, 2, |
406 reinterpret_cast<uint8_t*>(e.data.path), path_len)); | 388 Dart_NewStringFromUTF8( |
| 389 reinterpret_cast<uint8_t*>(e.data.path), path_len)); |
407 Dart_ListSetAt(event, 3, Dart_NewBoolean(true)); | 390 Dart_ListSetAt(event, 3, Dart_NewBoolean(true)); |
408 Dart_ListSetAt(event, 4, Dart_NewInteger(path_id)); | 391 Dart_ListSetAt(event, 4, Dart_NewInteger(path_id)); |
409 Dart_ListSetAt(events, i, event); | 392 Dart_ListSetAt(events, i, event); |
410 } | 393 } |
411 return events; | 394 return events; |
412 } | 395 } |
413 | 396 |
414 } // namespace bin | 397 } // namespace bin |
415 } // namespace dart | 398 } // namespace dart |
416 | 399 |
(...skipping 11 matching lines...) Expand all Loading... |
428 intptr_t FileSystemWatcher::GetSocketId(intptr_t id, intptr_t path_id) { | 411 intptr_t FileSystemWatcher::GetSocketId(intptr_t id, intptr_t path_id) { |
429 return -1; | 412 return -1; |
430 } | 413 } |
431 | 414 |
432 | 415 |
433 bool FileSystemWatcher::IsSupported() { | 416 bool FileSystemWatcher::IsSupported() { |
434 return false; | 417 return false; |
435 } | 418 } |
436 | 419 |
437 | 420 |
438 void FileSystemWatcher::UnwatchPath(intptr_t id, intptr_t path_id) { | 421 void FileSystemWatcher::UnwatchPath(intptr_t id, intptr_t path_id) {} |
439 } | |
440 | 422 |
441 | 423 |
442 intptr_t FileSystemWatcher::Init() { | 424 intptr_t FileSystemWatcher::Init() { |
443 return -1; | 425 return -1; |
444 } | 426 } |
445 | 427 |
446 | 428 |
447 void FileSystemWatcher::Close(intptr_t id) { | 429 void FileSystemWatcher::Close(intptr_t id) {} |
448 } | |
449 | 430 |
450 | 431 |
451 intptr_t FileSystemWatcher::WatchPath(intptr_t id, | 432 intptr_t FileSystemWatcher::WatchPath(intptr_t id, |
452 const char* path, | 433 const char* path, |
453 int events, | 434 int events, |
454 bool recursive) { | 435 bool recursive) { |
455 return -1; | 436 return -1; |
456 } | 437 } |
457 | 438 |
458 } // namespace bin | 439 } // namespace bin |
459 } // namespace dart | 440 } // namespace dart |
460 | 441 |
461 #endif // !TARGET_OS_IOS | 442 #endif // !TARGET_OS_IOS |
462 #endif // defined(TARGET_OS_MACOS) | 443 #endif // defined(TARGET_OS_MACOS) |
463 | 444 |
464 #endif // !defined(DART_IO_DISABLED) | 445 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |