From d114fd3f890781cf52b912c1a80bbc65c3c0326d Mon Sep 17 00:00:00 2001 From: Andrew Kolos Date: Thu, 25 Jul 2024 22:28:35 -0700 Subject: [PATCH 1/7] init --- packages/flutter_tools/lib/src/compile.dart | 118 ++++++++++-------- packages/flutter_tools/lib/src/devfs.dart | 2 +- .../lib/src/isolated/devfs_web.dart | 2 +- .../lib/src/isolated/resident_web_runner.dart | 4 +- .../lib/src/resident_runner.dart | 2 +- packages/flutter_tools/lib/src/run_hot.dart | 4 +- .../flutter_tools/lib/src/test/runner.dart | 2 +- .../lib/src/test/test_compiler.dart | 4 +- .../compile_incremental_test.dart | 2 +- .../test/general.shard/hot_shared.dart | 2 +- .../resident_runner_helpers.dart | 4 +- .../resident_web_runner_test.dart | 4 +- .../test/test_compiler_test.dart | 4 +- 13 files changed, 86 insertions(+), 68 deletions(-) diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart index f1ce205dbfc5b..4cb61033ed2b0 100644 --- a/packages/flutter_tools/lib/src/compile.dart +++ b/packages/flutter_tools/lib/src/compile.dart @@ -16,6 +16,7 @@ import 'base/file_system.dart'; import 'base/io.dart'; import 'base/logger.dart'; import 'base/platform.dart'; +import 'base/process.dart'; import 'build_info.dart'; import 'convert.dart'; @@ -589,7 +590,7 @@ abstract class ResidentCompiler { /// Should be invoked when results of compilation are accepted by the client. /// /// Either [accept] or [reject] should be called after every [recompile] call. - void accept(); + Future accept(); /// Should be invoked when results of compilation are rejected by the client. /// @@ -599,7 +600,7 @@ abstract class ResidentCompiler { /// Should be invoked when frontend server compiler should forget what was /// accepted previously so that next call to [recompile] produces complete /// kernel file. - void reset(); + Future reset(); Future shutdown(); } @@ -742,11 +743,9 @@ class DefaultResidentCompiler implements ResidentCompiler { final String inputKey = Uuid().generateV4(); if (nativeAssets != null && nativeAssets.isNotEmpty) { - server.stdin.writeln('native-assets $nativeAssets'); - _logger.printTrace('<- native-assets $nativeAssets'); + await _writelnToServerStdin('native-assets $nativeAssets', printTrace: true); } - server.stdin.writeln('recompile $mainUri $inputKey'); - _logger.printTrace('<- recompile $mainUri $inputKey'); + await _writelnToServerStdin('recompile $mainUri $inputKey', printTrace: true); final List? invalidatedFiles = request.invalidatedFiles; if (invalidatedFiles != null) { for (final Uri fileUri in invalidatedFiles) { @@ -761,8 +760,7 @@ class DefaultResidentCompiler implements ResidentCompiler { _logger.printTrace(message); } } - server.stdin.writeln(inputKey); - _logger.printTrace('<- $inputKey'); + await _writelnToServerStdin(inputKey, printTrace: true); return _stdoutHandler.compilerOutput?.future; } @@ -899,12 +897,10 @@ class DefaultResidentCompiler implements ResidentCompiler { })); if (nativeAssetsUri != null && nativeAssetsUri.isNotEmpty) { - _server?.stdin.writeln('native-assets $nativeAssetsUri'); - _logger.printTrace('<- native-assets $nativeAssetsUri'); + await _writelnToServerStdin('native assets $nativeAssetsUri', printTrace: true); } - _server?.stdin.writeln('compile $scriptUri'); - _logger.printTrace('<- compile $scriptUri'); + await _writelnToServerStdin('compile $scriptUri', printTrace: true); return _stdoutHandler.compilerOutput?.future; } @@ -945,24 +941,24 @@ class DefaultResidentCompiler implements ResidentCompiler { } final String inputKey = Uuid().generateV4(); - server.stdin - ..writeln('compile-expression $inputKey') - ..writeln(request.expression); - request.definitions?.forEach(server.stdin.writeln); - server.stdin.writeln(inputKey); - request.definitionTypes?.forEach(server.stdin.writeln); - server.stdin.writeln(inputKey); - request.typeDefinitions?.forEach(server.stdin.writeln); - server.stdin.writeln(inputKey); - request.typeBounds?.forEach(server.stdin.writeln); - server.stdin.writeln(inputKey); - request.typeDefaults?.forEach(server.stdin.writeln); - server.stdin - ..writeln(inputKey) - ..writeln(request.libraryUri ?? '') - ..writeln(request.klass ?? '') - ..writeln(request.method ?? '') - ..writeln(request.isStatic); + await _writelnToServerStdinAll([ + 'compile-expression $inputKey', + request.expression, + ...?request.definitions, + inputKey, + ...?request.definitionTypes, + inputKey, + ...?request.typeDefinitions, + inputKey, + ...?request.typeBounds, + inputKey, + ...?request.typeDefaults, + inputKey, + request.libraryUri ?? '', + request.klass ?? '', + request.method ?? '', + request.isStatic.toString(), + ]); return _stdoutHandler.compilerOutput?.future; } @@ -1000,27 +996,28 @@ class DefaultResidentCompiler implements ResidentCompiler { } final String inputKey = Uuid().generateV4(); - server.stdin - ..writeln('compile-expression-to-js $inputKey') - ..writeln(request.libraryUri ?? '') - ..writeln(request.line) - ..writeln(request.column); - request.jsModules?.forEach((String k, String v) { server.stdin.writeln('$k:$v'); }); - server.stdin.writeln(inputKey); - request.jsFrameValues?.forEach((String k, String v) { server.stdin.writeln('$k:$v'); }); - server.stdin - ..writeln(inputKey) - ..writeln(request.moduleName ?? '') - ..writeln(request.expression ?? ''); + await _writelnToServerStdinAll([ + 'compile-expression-to-js $inputKey', + request.libraryUri ?? '', + request.line.toString(), + request.column.toString(), + for (final MapEntry entry in request.jsModules?.entries ?? >[]) + '${entry.key}:${entry.value}', + inputKey, + for (final MapEntry entry in request.jsFrameValues?.entries ?? >[]) + '${entry.key}:${entry.value}', + inputKey, + request.moduleName ?? '', + request.expression ?? '' + ]); return _stdoutHandler.compilerOutput?.future; } @override - void accept() { + Future accept() async { if (_compileRequestNeedsConfirmation) { - _server?.stdin.writeln('accept'); - _logger.printTrace('<- accept'); + await _writelnToServerStdin('accept', printTrace: true); } _compileRequestNeedsConfirmation = false; } @@ -1041,16 +1038,14 @@ class DefaultResidentCompiler implements ResidentCompiler { return Future.value(); } _stdoutHandler.reset(expectSources: false); - _server?.stdin.writeln('reject'); - _logger.printTrace('<- reject'); + await _writelnToServerStdin('reject', printTrace: true); _compileRequestNeedsConfirmation = false; return _stdoutHandler.compilerOutput?.future; } @override - void reset() { - _server?.stdin.writeln('reset'); - _logger.printTrace('<- reset'); + Future reset() async { + await _writelnToServerStdin('reset', printTrace: true); } @override @@ -1064,6 +1059,29 @@ class DefaultResidentCompiler implements ResidentCompiler { server.kill(); return server.exitCode; } + + Future _writelnToServerStdin(String line, { + bool printTrace = false, + }) async { + final Process? server = _server; + if (server == null) { + return; + } + await ProcessUtils.writelnToStdinUnsafe(stdin: server.stdin, line: line); + if (printTrace) { + _logger.printTrace('<- $line'); + } + } + + Future _writelnToServerStdinAll(List? lines) async { + final Process? server = _server; + if (server == null) { + return; + } + for (final String line in lines ?? []) { + await ProcessUtils.writelnToStdinUnsafe(stdin: server.stdin, line: line); + } + } } /// Convert a file URI into a multi-root scheme URI if provided, otherwise diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart index a38e9824d19d1..33b6339d647e7 100644 --- a/packages/flutter_tools/lib/src/devfs.dart +++ b/packages/flutter_tools/lib/src/devfs.dart @@ -585,7 +585,7 @@ class DevFS { bool assetBuildFailed = false; int syncedBytes = 0; if (fullRestart) { - generator.reset(); + await generator.reset(); } // On a full restart, or on an initial compile for the attach based workflow, // this will produce a full dill. Subsequent invocations will produce incremental diff --git a/packages/flutter_tools/lib/src/isolated/devfs_web.dart b/packages/flutter_tools/lib/src/isolated/devfs_web.dart index 690278ba67052..dc7c5299219c2 100644 --- a/packages/flutter_tools/lib/src/isolated/devfs_web.dart +++ b/packages/flutter_tools/lib/src/isolated/devfs_web.dart @@ -1020,7 +1020,7 @@ class WebDevFS implements DevFS { await _validateTemplateFile('flutter_bootstrap.js'); final DateTime candidateCompileTime = DateTime.now(); if (fullRestart) { - generator.reset(); + await generator.reset(); } // The tool generates an entrypoint file in a temp directory to handle diff --git a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart index c212a0ed632d5..3a9d210a2ba2e 100644 --- a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart +++ b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart @@ -334,7 +334,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). appFailedToStart(); return 1; } - device!.generator!.accept(); + await device!.generator!.accept(); cacheInitialDillCompilation(); } else { final WebBuilder webBuilder = WebBuilder( @@ -418,7 +418,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). // Full restart is always false for web, since the extra recompile is wasteful. final UpdateFSReport report = await _updateDevFS(); if (report.success) { - device!.generator!.accept(); + await device!.generator!.accept(); } else { status.stop(); await device!.generator!.reject(); diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index daabad8b910ba..eefcf4ca3fe70 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -595,7 +595,7 @@ class FlutterDevice { Future updateReloadStatus(bool wasReloadSuccessful) async { if (wasReloadSuccessful) { - generator?.accept(); + await generator?.accept(); } else { await generator?.reject(); } diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index 2684e093b5604..b93724789007c 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -298,7 +298,7 @@ class HotRunner extends ResidentRunner { // VM must have accepted the kernel binary, there will be no reload // report, so we let incremental compiler know that source code was accepted. if (device!.generator != null) { - device.generator!.accept(); + await device.generator!.accept(); } final List views = await device.vmService!.getFlutterViews(); for (final FlutterView view in views) { @@ -626,7 +626,7 @@ class HotRunner extends ResidentRunner { // VM must have accepted the kernel binary, there will be no reload // report, so we let incremental compiler know that source code was accepted. if (device!.generator != null) { - device.generator!.accept(); + await device.generator!.accept(); } } // Check if the isolate is paused and resume it. diff --git a/packages/flutter_tools/lib/src/test/runner.dart b/packages/flutter_tools/lib/src/test/runner.dart index 7bbadbb9185de..3181ef676b716 100644 --- a/packages/flutter_tools/lib/src/test/runner.dart +++ b/packages/flutter_tools/lib/src/test/runner.dart @@ -647,7 +647,7 @@ class SpawnPlugin extends PlatformPlugin { fs: globals.fs, nativeAssetsYaml: nativeAssetsYaml, ); - residentCompiler.accept(); + await residentCompiler.accept(); globals.printTrace('Compiling ${sourceFile.absolute.uri} took ${compilerTime.elapsedMilliseconds}ms'); testTimeRecorder?.stop(TestTimePhases.Compile, testTimeRecorderStopwatch!); diff --git a/packages/flutter_tools/lib/src/test/test_compiler.dart b/packages/flutter_tools/lib/src/test/test_compiler.dart index 9c09ba92c409b..a94688e9852bb 100644 --- a/packages/flutter_tools/lib/src/test/test_compiler.dart +++ b/packages/flutter_tools/lib/src/test/test_compiler.dart @@ -209,8 +209,8 @@ class TestCompiler { } else { request.result.complete(outputPath); } - compiler!.accept(); - compiler!.reset(); + await compiler!.accept(); + await compiler!.reset(); } globals.printTrace('Compiling ${request.mainUri} took ${compilerTime.elapsedMilliseconds}ms'); testTimeRecorder?.stop(TestTimePhases.Compile, testTimeRecorderStopwatch!); diff --git a/packages/flutter_tools/test/general.shard/compile_incremental_test.dart b/packages/flutter_tools/test/general.shard/compile_incremental_test.dart index 14749ae1d458e..47c2a956fdf38 100644 --- a/packages/flutter_tools/test/general.shard/compile_incremental_test.dart +++ b/packages/flutter_tools/test/general.shard/compile_incremental_test.dart @@ -521,7 +521,7 @@ Future _accept( MemoryIOSink frontendServerStdIn, String expected, ) async { - generator.accept(); + await generator.accept(); final String commands = frontendServerStdIn.getAndClear(); final RegExp re = RegExp(expected); expect(commands, matches(re)); diff --git a/packages/flutter_tools/test/general.shard/hot_shared.dart b/packages/flutter_tools/test/general.shard/hot_shared.dart index 39f0aa0da57fc..c76f5397f166a 100644 --- a/packages/flutter_tools/test/general.shard/hot_shared.dart +++ b/packages/flutter_tools/test/general.shard/hot_shared.dart @@ -192,7 +192,7 @@ class TestHotRunnerConfig extends HotRunnerConfig { class FakeResidentCompiler extends Fake implements ResidentCompiler { @override - void accept() {} + Future accept() async {} } class FakeFlutterVmService extends Fake implements FlutterVmService { diff --git a/packages/flutter_tools/test/general.shard/resident_runner_helpers.dart b/packages/flutter_tools/test/general.shard/resident_runner_helpers.dart index 165c00d234de6..3bab03eb44ca5 100644 --- a/packages/flutter_tools/test/general.shard/resident_runner_helpers.dart +++ b/packages/flutter_tools/test/general.shard/resident_runner_helpers.dart @@ -346,10 +346,10 @@ class FakeResidentCompiler extends Fake implements ResidentCompiler { } @override - void accept() { } + Future accept() async {} @override - void reset() { } + Future reset() async {} } class FakeProjectFileInvalidator extends Fake implements ProjectFileInvalidator { diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart index 563b0eac3038f..67858cad08004 100644 --- a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart @@ -1508,10 +1508,10 @@ class FakeResidentCompiler extends Fake implements ResidentCompiler { } @override - void accept() {} + Future accept() async {} @override - void reset() {} + Future reset() async {} @override Future reject() async { diff --git a/packages/flutter_tools/test/general.shard/test/test_compiler_test.dart b/packages/flutter_tools/test/general.shard/test/test_compiler_test.dart index 257ad4f99966d..9585fbe9246a9 100644 --- a/packages/flutter_tools/test/general.shard/test/test_compiler_test.dart +++ b/packages/flutter_tools/test/general.shard/test/test_compiler_test.dart @@ -244,10 +244,10 @@ class FakeResidentCompiler extends Fake implements ResidentCompiler { } @override - void accept() { } + Future accept() async {} @override - void reset() { } + Future reset() async {} @override Future shutdown() async { From d1b5b434490701527363feef0b065a0522a5b4a2 Mon Sep 17 00:00:00 2001 From: Andrew Kolos Date: Fri, 26 Jul 2024 12:35:43 -0700 Subject: [PATCH 2/7] accept compiler result before notifying caller This is needed because the caller might call testTimeRecorder.print before this method got a chance to call testTimeRecorder.stop --- packages/flutter_tools/lib/src/test/test_compiler.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/flutter_tools/lib/src/test/test_compiler.dart b/packages/flutter_tools/lib/src/test/test_compiler.dart index a94688e9852bb..e1ac7d8e5c3a2 100644 --- a/packages/flutter_tools/lib/src/test/test_compiler.dart +++ b/packages/flutter_tools/lib/src/test/test_compiler.dart @@ -188,9 +188,11 @@ class TestCompiler { // compiler to avoid reusing compiler that might have gotten into // a weird state. if (outputPath == null || compilerOutput!.errorCount > 0) { - request.result.complete(); await _shutdown(); + request.result.complete(); } else { + await compiler!.accept(); + await compiler!.reset(); if (shouldCopyDillFile) { final String path = request.mainUri.toFilePath(windows: globals.platform.isWindows); final File outputFile = globals.fs.file(outputPath); @@ -209,8 +211,6 @@ class TestCompiler { } else { request.result.complete(outputPath); } - await compiler!.accept(); - await compiler!.reset(); } globals.printTrace('Compiling ${request.mainUri} took ${compilerTime.elapsedMilliseconds}ms'); testTimeRecorder?.stop(TestTimePhases.Compile, testTimeRecorderStopwatch!); From 755062196a92dc49b041209e0b8d0d3b95de82e7 Mon Sep 17 00:00:00 2001 From: Andrew Kolos Date: Fri, 26 Jul 2024 12:43:03 -0700 Subject: [PATCH 3/7] =?UTF-8?q?add=20more=20`await=20null`'s=20to=20`DevFS?= =?UTF-8?q?::update`=20=F0=9F=99=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/flutter_tools/lib/src/devfs.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart index 33b6339d647e7..f5f4ed3517d9d 100644 --- a/packages/flutter_tools/lib/src/devfs.dart +++ b/packages/flutter_tools/lib/src/devfs.dart @@ -614,6 +614,12 @@ class DevFS { // before processing bundle. _logger.printTrace('Processing bundle.'); // await null to give time for telling the compiler to compile. + // TODO(andrewkolos): This is a hack. Adding any more awaits to the compiler's + // recompile method will cause this to be insufficent. + // https://github.com/flutter/flutter/issues/151255. + await null; + await null; + await null; await null; // The tool writes the assets into the AssetBundle working dir so that they From b6c6c38afc900bce8cfdd9f05faa34b5bc60296b Mon Sep 17 00:00:00 2001 From: Andrew Kolos Date: Fri, 26 Jul 2024 11:00:11 -0700 Subject: [PATCH 4/7] use pool --- packages/flutter_tools/lib/src/compile.dart | 23 ++++++++++++--------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart index 4cb61033ed2b0..0092365a1cb07 100644 --- a/packages/flutter_tools/lib/src/compile.dart +++ b/packages/flutter_tools/lib/src/compile.dart @@ -7,6 +7,7 @@ import 'dart:typed_data'; import 'package:meta/meta.dart'; import 'package:package_config/package_config.dart'; +import 'package:pool/pool.dart'; import 'package:process/process.dart'; import 'package:usage/uuid/uuid.dart'; @@ -1063,24 +1064,26 @@ class DefaultResidentCompiler implements ResidentCompiler { Future _writelnToServerStdin(String line, { bool printTrace = false, }) async { - final Process? server = _server; - if (server == null) { - return; - } - await ProcessUtils.writelnToStdinUnsafe(stdin: server.stdin, line: line); - if (printTrace) { - _logger.printTrace('<- $line'); - } + await _writelnToServerStdinAll([line], printTrace: printTrace); } - Future _writelnToServerStdinAll(List? lines) async { + // TODO dont merge; explain why this is needed + final Pool _serverWritePool = Pool(1); + Future _writelnToServerStdinAll(List lines, { + bool printTrace = false, + }) async { final Process? server = _server; if (server == null) { return; } - for (final String line in lines ?? []) { + final PoolResource request = await _serverWritePool.request(); + for (final String line in lines) { await ProcessUtils.writelnToStdinUnsafe(stdin: server.stdin, line: line); + if (printTrace) { + _logger.printTrace('<- $line'); + } } + request.release(); } } From 648567c8accb3ddb98cbbd5f8fbc23a2f948c6a7 Mon Sep 17 00:00:00 2001 From: Andrew Kolos Date: Tue, 30 Jul 2024 13:36:41 -0700 Subject: [PATCH 5/7] add TODO about serializing writes --- .../flutter_tools/lib/src/base/process.dart | 13 +++++++++-- packages/flutter_tools/lib/src/compile.dart | 23 ++++++++++++------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart index 96df867826736..6ce3f57b45252 100644 --- a/packages/flutter_tools/lib/src/base/process.dart +++ b/packages/flutter_tools/lib/src/base/process.dart @@ -228,8 +228,11 @@ abstract class ProcessUtils { /// Write [line] to [stdin] and catch any errors with [onError]. /// - /// Specifically with [Process] file descriptors, an exception that is - /// thrown as part of a write can be most reliably caught with a + /// Concurrent calls to this method will result in an exception due to its + /// dependence on [IOSink.flush] (see https://github.com/dart-lang/sdk/issues/25277). + /// + /// Context: specifically with [Process] file descriptors, an exception that + /// is thrown as part of a write can be most reliably caught with a /// [ZoneSpecification] error handler. /// /// On some platforms, the following code appears to work: @@ -278,6 +281,9 @@ abstract class ProcessUtils { ); } + /// See [writelnToStdinGuarded]. + /// + /// In the event that the write or flush fails, this will throw an Exception. static Future writelnToStdinUnsafe({ required IOSink stdin, required String line, @@ -289,6 +295,9 @@ abstract class ProcessUtils { ); } + /// See [writeToStdinGuarded]. + /// + /// In the event that the write or flush fails, this will throw an Exception. static Future writeToStdinUnsafe({ required IOSink stdin, required String content, diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart index 0092365a1cb07..7e1dc89b896c8 100644 --- a/packages/flutter_tools/lib/src/compile.dart +++ b/packages/flutter_tools/lib/src/compile.dart @@ -1067,8 +1067,12 @@ class DefaultResidentCompiler implements ResidentCompiler { await _writelnToServerStdinAll([line], printTrace: printTrace); } - // TODO dont merge; explain why this is needed - final Pool _serverWritePool = Pool(1); + // TODO(andrewkolos): Concurrent calls to ProcessUtils.writelnToStdinUnsafe + // against the same stdin will result in an exception. To guard against this, + // we need to force calls to run serially. Ideally, this wouldn't be + // necessary since we shouldn't have multiple concurrent writes to the + // compiler process. However, we do (https://github.com/flutter/flutter/issues/152577). + final Pool _serverStdinWritePool = Pool(1); Future _writelnToServerStdinAll(List lines, { bool printTrace = false, }) async { @@ -1076,14 +1080,17 @@ class DefaultResidentCompiler implements ResidentCompiler { if (server == null) { return; } - final PoolResource request = await _serverWritePool.request(); - for (final String line in lines) { - await ProcessUtils.writelnToStdinUnsafe(stdin: server.stdin, line: line); - if (printTrace) { - _logger.printTrace('<- $line'); + final PoolResource request = await _serverStdinWritePool.request(); + try { + for (final String line in lines) { + await ProcessUtils.writelnToStdinUnsafe(stdin: server.stdin, line: line); + if (printTrace) { + _logger.printTrace('<- $line'); + } } + } finally { + request.release(); } - request.release(); } } From e5273a843581089ca281d62da1cdae3f2b4afe4a Mon Sep 17 00:00:00 2001 From: Andrew Kolos Date: Tue, 30 Jul 2024 14:53:21 -0700 Subject: [PATCH 6/7] tweak doc strings --- packages/flutter_tools/lib/src/base/process.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart index 6ce3f57b45252..0ae0a3f60156c 100644 --- a/packages/flutter_tools/lib/src/base/process.dart +++ b/packages/flutter_tools/lib/src/base/process.dart @@ -283,7 +283,8 @@ abstract class ProcessUtils { /// See [writelnToStdinGuarded]. /// - /// In the event that the write or flush fails, this will throw an Exception. + /// In the event that the write or flush fails, this will throw an exception + /// that preserves the stack trace of the callsite. static Future writelnToStdinUnsafe({ required IOSink stdin, required String line, @@ -297,7 +298,8 @@ abstract class ProcessUtils { /// See [writeToStdinGuarded]. /// - /// In the event that the write or flush fails, this will throw an Exception. + /// In the event that the write or flush fails, this will throw an exception + /// that preserves the stack trace of the callsite. static Future writeToStdinUnsafe({ required IOSink stdin, required String content, From 27d8c3c058671541d7b6b392ae4855be85eb3912 Mon Sep 17 00:00:00 2001 From: Andrew Kolos Date: Mon, 5 Aug 2024 14:31:31 -0700 Subject: [PATCH 7/7] experiment: avoid asynchronous suspensions where convenient --- packages/flutter_tools/lib/src/compile.dart | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart index 7e1dc89b896c8..c575ca795684f 100644 --- a/packages/flutter_tools/lib/src/compile.dart +++ b/packages/flutter_tools/lib/src/compile.dart @@ -1071,7 +1071,8 @@ class DefaultResidentCompiler implements ResidentCompiler { // against the same stdin will result in an exception. To guard against this, // we need to force calls to run serially. Ideally, this wouldn't be // necessary since we shouldn't have multiple concurrent writes to the - // compiler process. However, we do (https://github.com/flutter/flutter/issues/152577). + // compiler process. + // However, we do. See https://github.com/flutter/flutter/issues/152577. final Pool _serverStdinWritePool = Pool(1); Future _writelnToServerStdinAll(List lines, { bool printTrace = false, @@ -1082,8 +1083,12 @@ class DefaultResidentCompiler implements ResidentCompiler { } final PoolResource request = await _serverStdinWritePool.request(); try { + await ProcessUtils.writelnToStdinUnsafe( + stdin: server.stdin, + line: lines.join('\n'), + ); + for (final String line in lines) { - await ProcessUtils.writelnToStdinUnsafe(stdin: server.stdin, line: line); if (printTrace) { _logger.printTrace('<- $line'); } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy