@@ -12,6 +12,21 @@ export 'gen.dart';
1212
1313CPython ? _cpython;
1414String ? _logcatForwardingError;
15+ Future <void > _pythonRunQueue = Future <void >.value ();
16+ var _pythonRunSeq = 0 ;
17+
18+ Future <T > _enqueuePythonRun <T >(Future <T > Function () action) {
19+ final completer = Completer <T >();
20+ _pythonRunQueue = _pythonRunQueue.then ((_) async {
21+ try {
22+ completer.complete (await action ());
23+ } catch (e, st) {
24+ completer.completeError (e, st);
25+ }
26+ });
27+ return completer.future;
28+ }
29+
1530const _logcatInitScript = r'''
1631import sys
1732
@@ -45,21 +60,30 @@ CPython getCPython(String dynamicLibPath) {
4560
4661Future <String > runPythonProgramFFI (bool sync , String dynamicLibPath,
4762 String pythonProgramPath, String script) async {
48- if (sync ) {
49- // Sync run: do not involve ports (avoids GC/close races).
50- return _runPythonProgram (dynamicLibPath, pythonProgramPath, script);
51- } else {
52- // Async run: execute in a separate isolate and await exactly one result.
53- final receivePort = ReceivePort ();
54- try {
55- await Isolate .spawn (runPythonProgramInIsolate,
56- [receivePort.sendPort, dynamicLibPath, pythonProgramPath, script]);
57- final message = await receivePort.first;
58- return message is String ? message : message.toString ();
59- } finally {
60- receivePort.close ();
63+ return _enqueuePythonRun (() async {
64+ final runId = ++ _pythonRunSeq;
65+ spDebug (
66+ "Python run#$runId start (sync=$sync , script=${script .isNotEmpty }, program=$pythonProgramPath )" );
67+ if (sync ) {
68+ // Sync run: do not involve ports (avoids GC/close races).
69+ final result = _runPythonProgram (dynamicLibPath, pythonProgramPath, script);
70+ spDebug ("Python run#$runId done (resultLength=${result .length })" );
71+ return result;
72+ } else {
73+ // Async run: use Isolate.run() to avoid manual port lifecycle issues.
74+ try {
75+ final result = await Isolate .run (() =>
76+ _runPythonProgram (dynamicLibPath, pythonProgramPath, script));
77+ spDebug ("Python run#$runId done (resultLength=${result .length })" );
78+ return result;
79+ } catch (e, st) {
80+ final message = "Dart error running Python: $e \n $st " ;
81+ spDebug (message);
82+ spDebug ("Python run#$runId failed" );
83+ return message;
84+ }
6185 }
62- }
86+ });
6387}
6488
6589Future <String > runPythonProgramInIsolate (List <Object > arguments) async {
0 commit comments