mirror of
https://github.com/dart-lang/sdk
synced 2024-09-22 18:33:41 +00:00
Close file watcher when target is deleted.
BUG=http://code.google.com/p/dart/issues/detail?id=14374 R=sgjesse@google.com Review URL: https://codereview.chromium.org//39613002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@29159 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
faba61a261
commit
fdea26c768
|
@ -76,6 +76,7 @@ class _FileSystemWatcherImpl
|
|||
}
|
||||
var socket = new _RawSocket(new _NativeSocket.watch(socketId));
|
||||
_subscription = socket.expand((event) {
|
||||
bool stop = false;
|
||||
var events = [];
|
||||
var pair = {};
|
||||
if (event == RawSocketEvent.READ) {
|
||||
|
@ -87,18 +88,22 @@ class _FileSystemWatcherImpl
|
|||
}
|
||||
return path;
|
||||
}
|
||||
void add(event) {
|
||||
if ((event.type & _events) == 0) return;
|
||||
events.add(event);
|
||||
}
|
||||
while (socket.available() > 0) {
|
||||
for (var event in _readEvents()) {
|
||||
if (event == null) continue;
|
||||
var path = getPath(event);
|
||||
if ((event[0] & FileSystemEvent.CREATE) != 0) {
|
||||
events.add(new FileSystemCreateEvent._(path));
|
||||
add(new FileSystemCreateEvent._(path));
|
||||
}
|
||||
if ((event[0] & FileSystemEvent.MODIFY) != 0) {
|
||||
events.add(new FileSystemModifyEvent._(path, true));
|
||||
add(new FileSystemModifyEvent._(path, true));
|
||||
}
|
||||
if ((event[0] & FileSystemEvent._MODIFY_ATTRIBUTES) != 0) {
|
||||
events.add(new FileSystemModifyEvent._(path, false));
|
||||
add(new FileSystemModifyEvent._(path, false));
|
||||
}
|
||||
if ((event[0] & FileSystemEvent.MOVE) != 0) {
|
||||
int link = event[1];
|
||||
|
@ -111,11 +116,15 @@ class _FileSystemWatcherImpl
|
|||
pair[link] = event;
|
||||
}
|
||||
} else {
|
||||
events.add(new FileSystemMoveEvent._(path, null));
|
||||
add(new FileSystemMoveEvent._(path, null));
|
||||
}
|
||||
}
|
||||
if ((event[0] & FileSystemEvent.DELETE) != 0) {
|
||||
events.add(new FileSystemDeleteEvent._(path));
|
||||
add(new FileSystemDeleteEvent._(path));
|
||||
}
|
||||
if ((event[0] & FileSystemEvent._DELETE_SELF) != 0) {
|
||||
add(new FileSystemDeleteEvent._(path));
|
||||
stop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,9 +136,9 @@ class _FileSystemWatcherImpl
|
|||
} else {
|
||||
assert(false);
|
||||
}
|
||||
if (stop) socket.close();
|
||||
return events;
|
||||
})
|
||||
.where((event) => (event.type & _events) != 0)
|
||||
.listen(_controller.add, onDone: _cancel);
|
||||
}
|
||||
|
||||
|
@ -138,6 +147,7 @@ class _FileSystemWatcherImpl
|
|||
if (_subscription != null) {
|
||||
_subscription.cancel();
|
||||
}
|
||||
_controller.close();
|
||||
}
|
||||
|
||||
Stream<FileSystemEvent> get stream => _controller.stream;
|
||||
|
|
|
@ -24,7 +24,8 @@ class FileSystemWatcher {
|
|||
kModifyContent = 1 << 1,
|
||||
kDelete = 1 << 2,
|
||||
kMove = 1 << 3,
|
||||
kModefyAttribute = 1 << 4
|
||||
kModefyAttribute = 1 << 4,
|
||||
kDeleteSelf = 1 << 5
|
||||
};
|
||||
|
||||
struct Event {
|
||||
|
|
|
@ -24,7 +24,7 @@ intptr_t FileSystemWatcher::WatchPath(const char* path,
|
|||
bool recursive) {
|
||||
int fd = TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
|
||||
if (fd < 0) return -1;
|
||||
int list_events = 0;
|
||||
int list_events = IN_DELETE_SELF;
|
||||
if (events & kCreate) list_events |= IN_CREATE;
|
||||
if (events & kModifyContent) list_events |= IN_MODIFY | IN_ATTRIB;
|
||||
if (events & kDelete) list_events |= IN_DELETE;
|
||||
|
@ -56,7 +56,7 @@ Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id) {
|
|||
if (bytes < 0) {
|
||||
return DartUtils::NewDartOSError();
|
||||
}
|
||||
const intptr_t kMaxCount = kBufferSize / kEventSize + 1;
|
||||
const intptr_t kMaxCount = bytes / kEventSize;
|
||||
Dart_Handle events = Dart_NewList(kMaxCount);
|
||||
intptr_t offset = 0;
|
||||
intptr_t i = 0;
|
||||
|
@ -70,6 +70,7 @@ Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id) {
|
|||
if (e->mask & IN_CREATE) mask |= kCreate;
|
||||
if (e->mask & IN_MOVE) mask |= kMove;
|
||||
if (e->mask & IN_DELETE) mask |= kDelete;
|
||||
if (e->mask & IN_DELETE_SELF) mask |= kDeleteSelf;
|
||||
Dart_ListSetAt(event, 0, Dart_NewInteger(mask));
|
||||
Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie));
|
||||
if (e->len > 0) {
|
||||
|
|
|
@ -353,8 +353,13 @@ abstract class FileSystemEntity {
|
|||
* files and directories. Recursive watching is supported.
|
||||
*
|
||||
* The system will start listening for events once the returned [Stream] is
|
||||
* being listened to, not when the call to [watch] is issued. Note that the
|
||||
* returned [Stream] is endless. To stop the [Stream], cancel the subscription.
|
||||
* being listened to, not when the call to [watch] is issued.
|
||||
*
|
||||
* Note that the returned [Stream] is endless, unless:
|
||||
*
|
||||
* * The [Stream] is canceled, e.g. by calling `cancel` on the
|
||||
* [StreamSubscription].
|
||||
* * The [FileSystemEntity] being watches, is deleted.
|
||||
*/
|
||||
Stream<FileSystemEvent> watch({int events: FileSystemEvent.ALL,
|
||||
bool recursive: false})
|
||||
|
@ -623,6 +628,7 @@ class FileSystemEvent {
|
|||
static const int ALL = CREATE | MODIFY | DELETE | MOVE;
|
||||
|
||||
static const int _MODIFY_ATTRIBUTES = 1 << 4;
|
||||
static const int _DELETE_SELF = 1 << 5;
|
||||
|
||||
/**
|
||||
* The type of event. See [FileSystemEvent] for a list of events.
|
||||
|
|
|
@ -111,6 +111,24 @@ void testWatchDeleteFile() {
|
|||
}
|
||||
|
||||
|
||||
void testWatchDeleteDir() {
|
||||
var dir = Directory.systemTemp.createTempSync('dart_file_system_watcher');
|
||||
var watcher = dir.watch(events: 0);
|
||||
|
||||
asyncStart();
|
||||
var sub;
|
||||
sub = watcher.listen((event) {
|
||||
if (event is FileSystemDeleteEvent) {
|
||||
Expect.isTrue(event.path == dir.path);
|
||||
}
|
||||
}, onDone: () {
|
||||
asyncEnd();
|
||||
});
|
||||
|
||||
dir.deleteSync();
|
||||
}
|
||||
|
||||
|
||||
void testWatchOnlyModifyFile() {
|
||||
var dir = Directory.systemTemp.createTempSync('dart_file_system_watcher');
|
||||
var file = new File(dir.path + '/file');
|
||||
|
@ -244,6 +262,7 @@ void main() {
|
|||
testWatchModifyFile();
|
||||
testWatchMoveFile();
|
||||
testWatchDeleteFile();
|
||||
testWatchDeleteDir();
|
||||
testWatchOnlyModifyFile();
|
||||
testMultipleEvents();
|
||||
testWatchNonRecursive();
|
||||
|
|
Loading…
Reference in a new issue