OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |