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

Unified Diff: sdk/lib/io/directory_impl.dart

Issue 1893033002: Fixes memory leak of async directory lister (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Add unsupported calls Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/_internal/js_runtime/lib/io_patch.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/io/directory_impl.dart
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 620437c0e288d246ed29004d4de0429fe43a71fb..d76b86d83988a29832475e51735a738733f44390 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -252,6 +252,12 @@ class _Directory extends FileSystemEntity implements Directory {
}
}
+abstract class _AsyncDirectoryListerOps {
+ external factory _AsyncDirectoryListerOps(int pointer);
+
+ int getPointer();
+}
+
class _AsyncDirectoryLister {
static const int LIST_FILE = 0;
static const int LIST_DIRECTORY = 1;
@@ -269,10 +275,10 @@ class _AsyncDirectoryLister {
final bool followLinks;
StreamController controller;
- int id;
bool canceled = false;
bool nextRunning = false;
bool closed = false;
+ _AsyncDirectoryListerOps _ops;
Completer closeCompleter = new Completer();
_AsyncDirectoryLister(this.path, this.recursive, this.followLinks) {
@@ -282,13 +288,21 @@ class _AsyncDirectoryLister {
sync: true);
}
+ // Calling this function will increase the reference count on the native
+ // object that implements the async directory lister operations. It should
+ // only be called to pass the pointer to the IO Service, which will decrement
+ // the reference count when it is finished with it.
+ int _pointer() {
+ return (_ops == null) ? null : _ops.getPointer();
+ }
+
Stream get stream => controller.stream;
void onListen() {
_IOService._dispatch(_DIRECTORY_LIST_START, [path, recursive, followLinks])
.then((response) {
if (response is int) {
- id = response;
+ _ops = new _AsyncDirectoryListerOps(response);
next();
} else if (response is Error) {
controller.addError(response, response.stackTrace);
@@ -301,7 +315,9 @@ class _AsyncDirectoryLister {
}
void onResume() {
- if (!nextRunning) next();
+ if (!nextRunning) {
+ next();
+ }
}
Future onCancel() {
@@ -319,11 +335,15 @@ class _AsyncDirectoryLister {
close();
return;
}
- if (id == null) return;
- if (controller.isPaused) return;
- if (nextRunning) return;
+ if (controller.isPaused || nextRunning) {
+ return;
+ }
+ var pointer = _pointer();
+ if (pointer == null) {
+ return;
+ }
nextRunning = true;
- _IOService._dispatch(_DIRECTORY_LIST_NEXT, [id]).then((result) {
+ _IOService._dispatch(_DIRECTORY_LIST_NEXT, [pointer]).then((result) {
nextRunning = false;
if (result is List) {
next();
@@ -354,18 +374,27 @@ class _AsyncDirectoryLister {
});
}
+ void _cleanup() {
+ controller.close();
+ closeCompleter.complete();
+ _ops = null;
+ }
+
void close() {
- if (closed) return;
- if (nextRunning) return;
- void cleanup() {
- controller.close();
- closeCompleter.complete();
+ if (closed) {
+ return;
+ }
+ if (nextRunning) {
+ return;
}
closed = true;
- if (id != null) {
- _IOService._dispatch(_DIRECTORY_LIST_STOP, [id]).whenComplete(cleanup);
+
+ var pointer = _pointer();
+ if (pointer == null) {
+ _cleanup();
} else {
- cleanup();
+ _IOService._dispatch(_DIRECTORY_LIST_STOP, [pointer])
+ .whenComplete(_cleanup);
}
}
« no previous file with comments | « sdk/lib/_internal/js_runtime/lib/io_patch.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698