Skip to content

Commit 9509bd4

Browse files
committed
Limit the number of outstanding file reads in the VM loader
related dart-lang/test#373 [email protected] Review-Url: https://codereview.chromium.org/2626093003 .
1 parent f634059 commit 9509bd4

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

runtime/bin/vmservice/loader.dart

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ _enforceTrailingSlash(uri) {
5353
return uri;
5454
}
5555

56+
class FileRequest {
57+
final SendPort sp;
58+
final int tag;
59+
final Uri uri;
60+
final Uri resolvedUri;
61+
final String libraryUrl;
62+
FileRequest(this.sp, this.tag, this.uri, this.resolvedUri, this.libraryUrl);
63+
}
64+
5665
// State associated with the isolate that is used for loading.
5766
class IsolateLoaderState extends IsolateEmbedderData {
5867
IsolateLoaderState(this.isolateId);
@@ -78,6 +87,7 @@ class IsolateLoaderState extends IsolateEmbedderData {
7887
if (packagesConfigFlag != null) {
7988
_setPackagesConfig(packagesConfigFlag);
8089
}
90+
_fileRequestQueue = new List<FileRequest>();
8191
}
8292

8393
void cleanup() {
@@ -114,6 +124,24 @@ class IsolateLoaderState extends IsolateEmbedderData {
114124
Uri _packageConfig = null;
115125
Map<String, Uri> _packageMap = null;
116126

127+
// We issue only 16 concurrent calls to File.readAsBytes() to stay within
128+
// platform-specific resource limits (e.g. max open files). The rest go on
129+
// _fileRequestQueue and are processed when we can safely issue them.
130+
static const int _maxFileRequests = 16;
131+
int currentFileRequests = 0;
132+
List<FileRequest> _fileRequestQueue;
133+
134+
bool get shouldIssueFileRequest => currentFileRequests < _maxFileRequests;
135+
void enqueueFileRequest(FileRequest fr) {
136+
_fileRequestQueue.add(fr);
137+
}
138+
FileRequest dequeueFileRequest() {
139+
if (_fileRequestQueue.length == 0) {
140+
return null;
141+
}
142+
return _fileRequestQueue.removeAt(0);
143+
}
144+
117145
_setPackageRoot(String packageRoot) {
118146
packageRoot = _sanitizeWindowsPath(packageRoot);
119147
if (packageRoot.startsWith('file:') ||
@@ -399,7 +427,8 @@ void _loadHttp(SendPort sp,
399427
Timer.run(() {});
400428
}
401429

402-
void _loadFile(SendPort sp,
430+
void _loadFile(IsolateLoaderState loaderState,
431+
SendPort sp,
403432
int tag,
404433
Uri uri,
405434
Uri resolvedUri,
@@ -411,6 +440,17 @@ void _loadFile(SendPort sp,
411440
},
412441
onError: (e) {
413442
_sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, e.toString());
443+
}).whenComplete(() {
444+
loaderState.currentFileRequests--;
445+
while (loaderState.shouldIssueFileRequest) {
446+
FileRequest fr = loaderState.dequeueFileRequest();
447+
if (fr == null) {
448+
break;
449+
}
450+
_loadFile(
451+
loaderState, fr.sp, fr.tag, fr.uri, fr.resolvedUri, fr.libraryUrl);
452+
loaderState.currentFileRequests++;
453+
}
414454
});
415455
}
416456

@@ -507,7 +547,13 @@ _handleResourceRequest(IsolateLoaderState loaderState,
507547
Uri resolvedUri,
508548
String libraryUrl) {
509549
if (resolvedUri.scheme == '' || resolvedUri.scheme == 'file') {
510-
_loadFile(sp, tag, uri, resolvedUri, libraryUrl);
550+
if (loaderState.shouldIssueFileRequest) {
551+
_loadFile(loaderState, sp, tag, uri, resolvedUri, libraryUrl);
552+
loaderState.currentFileRequests++;
553+
} else {
554+
FileRequest fr = new FileRequest(sp, tag, uri, resolvedUri, libraryUrl);
555+
loaderState.enqueueFileRequest(fr);
556+
}
511557
} else if ((resolvedUri.scheme == 'http') ||
512558
(resolvedUri.scheme == 'https')) {
513559
_loadHttp(sp, tag, uri, resolvedUri, libraryUrl);

0 commit comments

Comments
 (0)