| Index: runtime/bin/vmservice/vmservice_io.dart
|
| diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
|
| index ed1d4732dc69770cace5b73738d5b822e6f9e694..680766a00825df177b6329a315b7cfd71b04b9f2 100644
|
| --- a/runtime/bin/vmservice/vmservice_io.dart
|
| +++ b/runtime/bin/vmservice/vmservice_io.dart
|
| @@ -71,11 +71,59 @@ Future deleteDirCallback(Uri path) async {
|
| await dir.delete(recursive: true);
|
| }
|
|
|
| +class PendingWrite {
|
| + PendingWrite(this.uri, this.bytes);
|
| + final Completer completer = new Completer();
|
| + final Uri uri;
|
| + final List<int> bytes;
|
| +
|
| + Future write() async {
|
| + var file = new File.fromUri(uri);
|
| + var parent_directory = file.parent;
|
| + await parent_directory.create(recursive: true);
|
| + var result = await file.writeAsBytes(bytes);
|
| + completer.complete(null);
|
| + WriteLimiter._writeCompleted();
|
| + }
|
| +}
|
| +
|
| +class WriteLimiter {
|
| + static final List<PendingWrite> pendingWrites = new List<PendingWrite>();
|
| +
|
| + // non-rooted Android devices have a very low limit for the number of
|
| + // open files. Artificially cap ourselves to 16.
|
| + static const kMaxOpenWrites = 16;
|
| + static int openWrites = 0;
|
| +
|
| + static Future scheduleWrite(Uri path, List<int> bytes) async {
|
| + // Create a new pending write.
|
| + PendingWrite pw = new PendingWrite(path, bytes);
|
| + pendingWrites.add(pw);
|
| + _maybeWriteFiles();
|
| + return pw.completer.future;
|
| + }
|
| +
|
| + static _maybeWriteFiles() {
|
| + while (openWrites < kMaxOpenWrites) {
|
| + if (pendingWrites.length > 0) {
|
| + PendingWrite pw = pendingWrites.removeLast();
|
| + pw.write();
|
| + openWrites++;
|
| + } else {
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +
|
| + static _writeCompleted() {
|
| + openWrites--;
|
| + assert(openWrites >= 0);
|
| + _maybeWriteFiles();
|
| + }
|
| +}
|
| +
|
| Future writeFileCallback(Uri path, List<int> bytes) async {
|
| - var file = new File.fromUri(path);
|
| - var parent_directory = file.parent;
|
| - await parent_directory.create(recursive: true);
|
| - await file.writeAsBytes(bytes);
|
| + return WriteLimiter.scheduleWrite(path, bytes);
|
| }
|
|
|
| Future<List<int>> readFileCallback(Uri path) async {
|
|
|