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

Side by Side Diff: runtime/bin/vmservice/loader.dart

Issue 2626093003: Limit the number of outstanding file reads in the VM loader (Closed)
Patch Set: Created 3 years, 11 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of vmservice_io; 5 part of vmservice_io;
6 6
7 _sanitizeWindowsPath(path) { 7 _sanitizeWindowsPath(path) {
8 // For Windows we need to massage the paths a bit according to 8 // For Windows we need to massage the paths a bit according to
9 // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx 9 // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
10 // 10 //
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 } 46 }
47 47
48 // Ensure we have a trailing slash character. 48 // Ensure we have a trailing slash character.
49 _enforceTrailingSlash(uri) { 49 _enforceTrailingSlash(uri) {
50 if (!uri.endsWith('/')) { 50 if (!uri.endsWith('/')) {
51 return '$uri/'; 51 return '$uri/';
52 } 52 }
53 return uri; 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 // State associated with the isolate that is used for loading. 65 // State associated with the isolate that is used for loading.
57 class IsolateLoaderState extends IsolateEmbedderData { 66 class IsolateLoaderState extends IsolateEmbedderData {
58 IsolateLoaderState(this.isolateId); 67 IsolateLoaderState(this.isolateId);
59 68
60 final int isolateId; 69 final int isolateId;
61 70
62 SendPort sp; 71 SendPort sp;
63 72
64 void init(String packageRootFlag, 73 void init(String packageRootFlag,
65 String packagesConfigFlag, 74 String packagesConfigFlag,
66 String workingDirectory, 75 String workingDirectory,
67 String rootScript) { 76 String rootScript) {
68 // _workingDirectory must be set first. 77 // _workingDirectory must be set first.
69 _workingDirectory = new Uri.directory(workingDirectory); 78 _workingDirectory = new Uri.directory(workingDirectory);
70 if (rootScript != null) { 79 if (rootScript != null) {
71 _rootScript = Uri.parse(rootScript); 80 _rootScript = Uri.parse(rootScript);
72 } 81 }
73 // If the --package-root flag was passed. 82 // If the --package-root flag was passed.
74 if (packageRootFlag != null) { 83 if (packageRootFlag != null) {
75 _setPackageRoot(packageRootFlag); 84 _setPackageRoot(packageRootFlag);
76 } 85 }
77 // If the --packages flag was passed. 86 // If the --packages flag was passed.
78 if (packagesConfigFlag != null) { 87 if (packagesConfigFlag != null) {
79 _setPackagesConfig(packagesConfigFlag); 88 _setPackagesConfig(packagesConfigFlag);
80 } 89 }
90 _fileRequestQueue = new List<FileRequest>();
81 } 91 }
82 92
83 void cleanup() { 93 void cleanup() {
84 if (_packagesPort != null) { 94 if (_packagesPort != null) {
85 _packagesPort.close(); 95 _packagesPort.close();
86 _packagesPort = null; 96 _packagesPort = null;
87 } 97 }
88 } 98 }
89 99
90 // The working directory when the embedder started. 100 // The working directory when the embedder started.
(...skipping 16 matching lines...) Expand all
107 String _packageError = null; 117 String _packageError = null;
108 118
109 // The directory to look in to resolve "package:" scheme URIs. By default it 119 // The directory to look in to resolve "package:" scheme URIs. By default it
110 // is the 'packages' directory right next to the script. 120 // is the 'packages' directory right next to the script.
111 Uri _packageRoot = null; 121 Uri _packageRoot = null;
112 122
113 // The map describing how certain package names are mapped to Uris. 123 // The map describing how certain package names are mapped to Uris.
114 Uri _packageConfig = null; 124 Uri _packageConfig = null;
115 Map<String, Uri> _packageMap = null; 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 _setPackageRoot(String packageRoot) { 145 _setPackageRoot(String packageRoot) {
118 packageRoot = _sanitizeWindowsPath(packageRoot); 146 packageRoot = _sanitizeWindowsPath(packageRoot);
119 if (packageRoot.startsWith('file:') || 147 if (packageRoot.startsWith('file:') ||
120 packageRoot.startsWith('http:') || 148 packageRoot.startsWith('http:') ||
121 packageRoot.startsWith('https:')) { 149 packageRoot.startsWith('https:')) {
122 packageRoot = _enforceTrailingSlash(packageRoot); 150 packageRoot = _enforceTrailingSlash(packageRoot);
123 _packageRoot = _workingDirectory.resolve(packageRoot); 151 _packageRoot = _workingDirectory.resolve(packageRoot);
124 } else { 152 } else {
125 packageRoot = _sanitizeWindowsPath(packageRoot); 153 packageRoot = _sanitizeWindowsPath(packageRoot);
126 packageRoot = _trimWindowsPath(packageRoot); 154 packageRoot = _trimWindowsPath(packageRoot);
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 }) 420 })
393 .catchError((e) { 421 .catchError((e) {
394 _sendResourceResponse( 422 _sendResourceResponse(
395 sp, tag, uri, resolvedUri, libraryUrl, e.toString()); 423 sp, tag, uri, resolvedUri, libraryUrl, e.toString());
396 }); 424 });
397 // It's just here to push an event on the event loop so that we invoke the 425 // It's just here to push an event on the event loop so that we invoke the
398 // scheduled microtasks. 426 // scheduled microtasks.
399 Timer.run(() {}); 427 Timer.run(() {});
400 } 428 }
401 429
402 void _loadFile(SendPort sp, 430 void _loadFile(IsolateLoaderState loaderState,
431 SendPort sp,
403 int tag, 432 int tag,
404 Uri uri, 433 Uri uri,
405 Uri resolvedUri, 434 Uri resolvedUri,
406 String libraryUrl) { 435 String libraryUrl) {
407 var path = resolvedUri.toFilePath(); 436 var path = resolvedUri.toFilePath();
408 var sourceFile = new File(path); 437 var sourceFile = new File(path);
409 sourceFile.readAsBytes().then((data) { 438 sourceFile.readAsBytes().then((data) {
410 _sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, data); 439 _sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, data);
411 }, 440 },
412 onError: (e) { 441 onError: (e) {
413 _sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, e.toString()); 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
417 void _loadDataUri(SendPort sp, 457 void _loadDataUri(SendPort sp,
418 int tag, 458 int tag,
419 Uri uri, 459 Uri uri,
420 Uri resolvedUri, 460 Uri resolvedUri,
421 String libraryUrl) { 461 String libraryUrl) {
422 try { 462 try {
423 var mime = uri.data.mimeType; 463 var mime = uri.data.mimeType;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 // TODO(johnmccutchan): This and most other top level functions in this file 540 // TODO(johnmccutchan): This and most other top level functions in this file
501 // should be turned into methods on the IsolateLoaderState class. 541 // should be turned into methods on the IsolateLoaderState class.
502 _handleResourceRequest(IsolateLoaderState loaderState, 542 _handleResourceRequest(IsolateLoaderState loaderState,
503 SendPort sp, 543 SendPort sp,
504 bool traceLoading, 544 bool traceLoading,
505 int tag, 545 int tag,
506 Uri uri, 546 Uri uri,
507 Uri resolvedUri, 547 Uri resolvedUri,
508 String libraryUrl) { 548 String libraryUrl) {
509 if (resolvedUri.scheme == '' || resolvedUri.scheme == 'file') { 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 } else if ((resolvedUri.scheme == 'http') || 557 } else if ((resolvedUri.scheme == 'http') ||
512 (resolvedUri.scheme == 'https')) { 558 (resolvedUri.scheme == 'https')) {
513 _loadHttp(sp, tag, uri, resolvedUri, libraryUrl); 559 _loadHttp(sp, tag, uri, resolvedUri, libraryUrl);
514 } else if ((resolvedUri.scheme == 'data')) { 560 } else if ((resolvedUri.scheme == 'data')) {
515 _loadDataUri(sp, tag, uri, resolvedUri, libraryUrl); 561 _loadDataUri(sp, tag, uri, resolvedUri, libraryUrl);
516 } else if ((resolvedUri.scheme == 'package')) { 562 } else if ((resolvedUri.scheme == 'package')) {
517 _loadPackage(loaderState, 563 _loadPackage(loaderState,
518 sp, 564 sp,
519 traceLoading, 565 traceLoading,
520 tag, 566 tag,
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 _log('Unknown scheme (${pathUri.scheme}) in $pathUri.'); 1112 _log('Unknown scheme (${pathUri.scheme}) in $pathUri.');
1067 } 1113 }
1068 _sendExtensionImportResponse(sp, uri, libraryUri, null); 1114 _sendExtensionImportResponse(sp, uri, libraryUri, null);
1069 break; 1115 break;
1070 } 1116 }
1071 break; 1117 break;
1072 default: 1118 default:
1073 _log('Unknown loader request tag=$tag from $isolateId'); 1119 _log('Unknown loader request tag=$tag from $isolateId');
1074 } 1120 }
1075 } 1121 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698