mirror of
https://github.com/dart-lang/sdk
synced 2024-09-22 20:34:31 +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));
|
var socket = new _RawSocket(new _NativeSocket.watch(socketId));
|
||||||
_subscription = socket.expand((event) {
|
_subscription = socket.expand((event) {
|
||||||
|
bool stop = false;
|
||||||
var events = [];
|
var events = [];
|
||||||
var pair = {};
|
var pair = {};
|
||||||
if (event == RawSocketEvent.READ) {
|
if (event == RawSocketEvent.READ) {
|
||||||
|
@ -87,18 +88,22 @@ class _FileSystemWatcherImpl
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
void add(event) {
|
||||||
|
if ((event.type & _events) == 0) return;
|
||||||
|
events.add(event);
|
||||||
|
}
|
||||||
while (socket.available() > 0) {
|
while (socket.available() > 0) {
|
||||||
for (var event in _readEvents()) {
|
for (var event in _readEvents()) {
|
||||||
if (event == null) continue;
|
if (event == null) continue;
|
||||||
var path = getPath(event);
|
var path = getPath(event);
|
||||||
if ((event[0] & FileSystemEvent.CREATE) != 0) {
|
if ((event[0] & FileSystemEvent.CREATE) != 0) {
|
||||||
events.add(new FileSystemCreateEvent._(path));
|
add(new FileSystemCreateEvent._(path));
|
||||||
}
|
}
|
||||||
if ((event[0] & FileSystemEvent.MODIFY) != 0) {
|
if ((event[0] & FileSystemEvent.MODIFY) != 0) {
|
||||||
events.add(new FileSystemModifyEvent._(path, true));
|
add(new FileSystemModifyEvent._(path, true));
|
||||||
}
|
}
|
||||||
if ((event[0] & FileSystemEvent._MODIFY_ATTRIBUTES) != 0) {
|
if ((event[0] & FileSystemEvent._MODIFY_ATTRIBUTES) != 0) {
|
||||||
events.add(new FileSystemModifyEvent._(path, false));
|
add(new FileSystemModifyEvent._(path, false));
|
||||||
}
|
}
|
||||||
if ((event[0] & FileSystemEvent.MOVE) != 0) {
|
if ((event[0] & FileSystemEvent.MOVE) != 0) {
|
||||||
int link = event[1];
|
int link = event[1];
|
||||||
|
@ -111,11 +116,15 @@ class _FileSystemWatcherImpl
|
||||||
pair[link] = event;
|
pair[link] = event;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
events.add(new FileSystemMoveEvent._(path, null));
|
add(new FileSystemMoveEvent._(path, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((event[0] & FileSystemEvent.DELETE) != 0) {
|
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 {
|
} else {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
if (stop) socket.close();
|
||||||
return events;
|
return events;
|
||||||
})
|
})
|
||||||
.where((event) => (event.type & _events) != 0)
|
|
||||||
.listen(_controller.add, onDone: _cancel);
|
.listen(_controller.add, onDone: _cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +147,7 @@ class _FileSystemWatcherImpl
|
||||||
if (_subscription != null) {
|
if (_subscription != null) {
|
||||||
_subscription.cancel();
|
_subscription.cancel();
|
||||||
}
|
}
|
||||||
|
_controller.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<FileSystemEvent> get stream => _controller.stream;
|
Stream<FileSystemEvent> get stream => _controller.stream;
|
||||||
|
|
|
@ -24,7 +24,8 @@ class FileSystemWatcher {
|
||||||
kModifyContent = 1 << 1,
|
kModifyContent = 1 << 1,
|
||||||
kDelete = 1 << 2,
|
kDelete = 1 << 2,
|
||||||
kMove = 1 << 3,
|
kMove = 1 << 3,
|
||||||
kModefyAttribute = 1 << 4
|
kModefyAttribute = 1 << 4,
|
||||||
|
kDeleteSelf = 1 << 5
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Event {
|
struct Event {
|
||||||
|
|
|
@ -24,7 +24,7 @@ intptr_t FileSystemWatcher::WatchPath(const char* path,
|
||||||
bool recursive) {
|
bool recursive) {
|
||||||
int fd = TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
|
int fd = TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
|
||||||
if (fd < 0) return -1;
|
if (fd < 0) return -1;
|
||||||
int list_events = 0;
|
int list_events = IN_DELETE_SELF;
|
||||||
if (events & kCreate) list_events |= IN_CREATE;
|
if (events & kCreate) list_events |= IN_CREATE;
|
||||||
if (events & kModifyContent) list_events |= IN_MODIFY | IN_ATTRIB;
|
if (events & kModifyContent) list_events |= IN_MODIFY | IN_ATTRIB;
|
||||||
if (events & kDelete) list_events |= IN_DELETE;
|
if (events & kDelete) list_events |= IN_DELETE;
|
||||||
|
@ -56,7 +56,7 @@ Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id) {
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
return DartUtils::NewDartOSError();
|
return DartUtils::NewDartOSError();
|
||||||
}
|
}
|
||||||
const intptr_t kMaxCount = kBufferSize / kEventSize + 1;
|
const intptr_t kMaxCount = bytes / kEventSize;
|
||||||
Dart_Handle events = Dart_NewList(kMaxCount);
|
Dart_Handle events = Dart_NewList(kMaxCount);
|
||||||
intptr_t offset = 0;
|
intptr_t offset = 0;
|
||||||
intptr_t i = 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_CREATE) mask |= kCreate;
|
||||||
if (e->mask & IN_MOVE) mask |= kMove;
|
if (e->mask & IN_MOVE) mask |= kMove;
|
||||||
if (e->mask & IN_DELETE) mask |= kDelete;
|
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, 0, Dart_NewInteger(mask));
|
||||||
Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie));
|
Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie));
|
||||||
if (e->len > 0) {
|
if (e->len > 0) {
|
||||||
|
|
|
@ -353,8 +353,13 @@ abstract class FileSystemEntity {
|
||||||
* files and directories. Recursive watching is supported.
|
* files and directories. Recursive watching is supported.
|
||||||
*
|
*
|
||||||
* The system will start listening for events once the returned [Stream] is
|
* 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
|
* being listened to, not when the call to [watch] is issued.
|
||||||
* returned [Stream] is endless. To stop the [Stream], cancel the subscription.
|
*
|
||||||
|
* 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,
|
Stream<FileSystemEvent> watch({int events: FileSystemEvent.ALL,
|
||||||
bool recursive: false})
|
bool recursive: false})
|
||||||
|
@ -623,6 +628,7 @@ class FileSystemEvent {
|
||||||
static const int ALL = CREATE | MODIFY | DELETE | MOVE;
|
static const int ALL = CREATE | MODIFY | DELETE | MOVE;
|
||||||
|
|
||||||
static const int _MODIFY_ATTRIBUTES = 1 << 4;
|
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.
|
* 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() {
|
void testWatchOnlyModifyFile() {
|
||||||
var dir = Directory.systemTemp.createTempSync('dart_file_system_watcher');
|
var dir = Directory.systemTemp.createTempSync('dart_file_system_watcher');
|
||||||
var file = new File(dir.path + '/file');
|
var file = new File(dir.path + '/file');
|
||||||
|
@ -244,6 +262,7 @@ void main() {
|
||||||
testWatchModifyFile();
|
testWatchModifyFile();
|
||||||
testWatchMoveFile();
|
testWatchMoveFile();
|
||||||
testWatchDeleteFile();
|
testWatchDeleteFile();
|
||||||
|
testWatchDeleteDir();
|
||||||
testWatchOnlyModifyFile();
|
testWatchOnlyModifyFile();
|
||||||
testMultipleEvents();
|
testMultipleEvents();
|
||||||
testWatchNonRecursive();
|
testWatchNonRecursive();
|
||||||
|
|
Loading…
Reference in a new issue