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

Side by Side Diff: lib/src/directory_watcher/mac_os.dart

Issue 995623002: Fix bugs where events could be added after watchers were closed. (Closed) Base URL: git@github.com:dart-lang/watcher@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « lib/src/directory_watcher/linux.dart ('k') | pubspec.yaml » ('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 (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 library watcher.directory_watcher.mac_os; 5 library watcher.directory_watcher.mac_os;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:io'; 8 import 'dart:io';
9 9
10 import 'package:path/path.dart' as p; 10 import 'package:path/path.dart' as p;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 /// The subscription to the stream returned by [Directory.watch]. 62 /// The subscription to the stream returned by [Directory.watch].
63 /// 63 ///
64 /// This is separate from [_subscriptions] because this stream occasionally 64 /// This is separate from [_subscriptions] because this stream occasionally
65 /// needs to be resubscribed in order to work around issue 14849. 65 /// needs to be resubscribed in order to work around issue 14849.
66 StreamSubscription<FileSystemEvent> _watchSubscription; 66 StreamSubscription<FileSystemEvent> _watchSubscription;
67 67
68 /// The subscription to the [Directory.list] call for the initial listing of 68 /// The subscription to the [Directory.list] call for the initial listing of
69 /// the directory to determine its initial state. 69 /// the directory to determine its initial state.
70 StreamSubscription<FileSystemEntity> _initialListSubscription; 70 StreamSubscription<FileSystemEntity> _initialListSubscription;
71 71
72 /// The subscription to the [Directory.list] call for listing the contents of 72 /// The subscriptions to [Directory.list] calls for listing the contents of a
73 /// a subdirectory that was moved into the watched directory. 73 /// subdirectory that was moved into the watched directory.
74 StreamSubscription<FileSystemEntity> _listSubscription; 74 final _listSubscriptions = new Set<StreamSubscription<FileSystemEntity>>();
75 75
76 /// The timer for tracking how long we wait for an initial batch of bogus 76 /// The timer for tracking how long we wait for an initial batch of bogus
77 /// events (see issue 14373). 77 /// events (see issue 14373).
78 Timer _bogusEventTimer; 78 Timer _bogusEventTimer;
79 79
80 _MacOSDirectoryWatcher(String directory, int parentId) 80 _MacOSDirectoryWatcher(String directory, int parentId)
81 : directory = directory, 81 : directory = directory,
82 _files = new PathSet(directory), 82 _files = new PathSet(directory),
83 _id = "$parentId/${_count++}" { 83 _id = "$parentId/${_count++}" {
84 _startWatch(); 84 _startWatch();
(...skipping 21 matching lines...) Expand all
106 _readyCompleter.complete(); 106 _readyCompleter.complete();
107 }); 107 });
108 } 108 }
109 109
110 void close() { 110 void close() {
111 if (MacOSDirectoryWatcher.logDebugInfo) { 111 if (MacOSDirectoryWatcher.logDebugInfo) {
112 print("[$_id] watcher is closed\n${new Chain.current().terse}"); 112 print("[$_id] watcher is closed\n${new Chain.current().terse}");
113 } 113 }
114 if (_watchSubscription != null) _watchSubscription.cancel(); 114 if (_watchSubscription != null) _watchSubscription.cancel();
115 if (_initialListSubscription != null) _initialListSubscription.cancel(); 115 if (_initialListSubscription != null) _initialListSubscription.cancel();
116 if (_listSubscription != null) _listSubscription.cancel();
117 _watchSubscription = null; 116 _watchSubscription = null;
118 _initialListSubscription = null; 117 _initialListSubscription = null;
119 _listSubscription = null; 118
119 for (var subscription in _listSubscriptions) {
120 subscription.cancel();
121 }
122 _listSubscriptions.clear();
123
120 _eventsController.close(); 124 _eventsController.close();
121 } 125 }
122 126
123 /// The callback that's run when [Directory.watch] emits a batch of events. 127 /// The callback that's run when [Directory.watch] emits a batch of events.
124 void _onBatch(List<FileSystemEvent> batch) { 128 void _onBatch(List<FileSystemEvent> batch) {
125 if (MacOSDirectoryWatcher.logDebugInfo) { 129 if (MacOSDirectoryWatcher.logDebugInfo) {
126 print("[$_id] ======== batch:"); 130 print("[$_id] ======== batch:");
127 for (var event in batch) { 131 for (var event in batch) {
128 print("[$_id] ${_formatEvent(event)}"); 132 print("[$_id] ${_formatEvent(event)}");
129 } 133 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 // that happened prior to the watch beginning. 188 // that happened prior to the watch beginning.
185 if (_files.contains(path)) continue; 189 if (_files.contains(path)) continue;
186 190
187 _emitEvent(ChangeType.ADD, path); 191 _emitEvent(ChangeType.ADD, path);
188 _files.add(path); 192 _files.add(path);
189 continue; 193 continue;
190 } 194 }
191 195
192 if (_files.containsDir(path)) continue; 196 if (_files.containsDir(path)) continue;
193 197
194 var stream = Chain.track(new Directory(path).list(recursive: true)); 198 var subscription;
195 _listSubscription = stream.listen((entity) { 199 subscription = Chain.track(new Directory(path).list(recursive: true))
200 .listen((entity) {
196 if (entity is Directory) return; 201 if (entity is Directory) return;
197 if (_files.contains(path)) return; 202 if (_files.contains(path)) return;
198 203
199 _emitEvent(ChangeType.ADD, entity.path); 204 _emitEvent(ChangeType.ADD, entity.path);
200 _files.add(entity.path); 205 _files.add(entity.path);
201 }, onError: (e, stackTrace) { 206 }, onError: (e, stackTrace) {
202 if (MacOSDirectoryWatcher.logDebugInfo) { 207 if (MacOSDirectoryWatcher.logDebugInfo) {
203 print("[$_id] got error listing $relativePath: $e"); 208 print("[$_id] got error listing $relativePath: $e");
204 } 209 }
205 _emitError(e, stackTrace); 210 _emitError(e, stackTrace);
211 }, onDone: () {
212 _listSubscriptions.remove(subscription);
206 }, cancelOnError: true); 213 }, cancelOnError: true);
214 _listSubscriptions.add(subscription);
207 } else if (event is FileSystemModifyEvent) { 215 } else if (event is FileSystemModifyEvent) {
208 assert(!event.isDirectory); 216 assert(!event.isDirectory);
209 _emitEvent(ChangeType.MODIFY, path); 217 _emitEvent(ChangeType.MODIFY, path);
210 } else { 218 } else {
211 assert(event is FileSystemDeleteEvent); 219 assert(event is FileSystemDeleteEvent);
212 for (var removedPath in _files.remove(path)) { 220 for (var removedPath in _files.remove(path)) {
213 _emitEvent(ChangeType.REMOVE, removedPath); 221 _emitEvent(ChangeType.REMOVE, removedPath);
214 } 222 }
215 } 223 }
216 } 224 }
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 } else if (event is FileSystemDeleteEvent) { 496 } else if (event is FileSystemDeleteEvent) {
489 return "delete $type $path"; 497 return "delete $type $path";
490 } else if (event is FileSystemModifyEvent) { 498 } else if (event is FileSystemModifyEvent) {
491 return "modify $type $path"; 499 return "modify $type $path";
492 } else if (event is FileSystemMoveEvent) { 500 } else if (event is FileSystemMoveEvent) {
493 return "move $type $path to " 501 return "move $type $path to "
494 "${p.relative(event.destination, from: directory)}"; 502 "${p.relative(event.destination, from: directory)}";
495 } 503 }
496 } 504 }
497 } 505 }
OLDNEW
« no previous file with comments | « lib/src/directory_watcher/linux.dart ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698