@@ -53,6 +53,15 @@ _enforceTrailingSlash(uri) {
53
53
return uri;
54
54
}
55
55
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
+
56
65
// State associated with the isolate that is used for loading.
57
66
class IsolateLoaderState extends IsolateEmbedderData {
58
67
IsolateLoaderState (this .isolateId);
@@ -78,6 +87,7 @@ class IsolateLoaderState extends IsolateEmbedderData {
78
87
if (packagesConfigFlag != null ) {
79
88
_setPackagesConfig (packagesConfigFlag);
80
89
}
90
+ _fileRequestQueue = new List <FileRequest >();
81
91
}
82
92
83
93
void cleanup () {
@@ -114,6 +124,24 @@ class IsolateLoaderState extends IsolateEmbedderData {
114
124
Uri _packageConfig = null ;
115
125
Map <String , Uri > _packageMap = null ;
116
126
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
+
117
145
_setPackageRoot (String packageRoot) {
118
146
packageRoot = _sanitizeWindowsPath (packageRoot);
119
147
if (packageRoot.startsWith ('file:' ) ||
@@ -399,7 +427,8 @@ void _loadHttp(SendPort sp,
399
427
Timer .run (() {});
400
428
}
401
429
402
- void _loadFile (SendPort sp,
430
+ void _loadFile (IsolateLoaderState loaderState,
431
+ SendPort sp,
403
432
int tag,
404
433
Uri uri,
405
434
Uri resolvedUri,
@@ -411,6 +440,17 @@ void _loadFile(SendPort sp,
411
440
},
412
441
onError: (e) {
413
442
_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
+ }
414
454
});
415
455
}
416
456
@@ -507,7 +547,13 @@ _handleResourceRequest(IsolateLoaderState loaderState,
507
547
Uri resolvedUri,
508
548
String libraryUrl) {
509
549
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
+ }
511
557
} else if ((resolvedUri.scheme == 'http' ) ||
512
558
(resolvedUri.scheme == 'https' )) {
513
559
_loadHttp (sp, tag, uri, resolvedUri, libraryUrl);
0 commit comments