-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
This issue is in spirit a continuation of #51254; I'm just picking up where that issue left off.
I would have assumed that since that issue was closed and Dart_EnterIsolate/Dart_ExitIsolate are now part of the public API, dart:io's sync functions would have been updated to call these methods themselves. However this doesn't seem to be the case, and calling sync functions in many isolates at once can still cause an isolate group to hang.
Example:
import 'dart:async';
import 'dart:io';
import 'dart:isolate';
void main() async {
print('Main isolate alive!');
Timer.periodic(
Duration(milliseconds: 100),
(_) => print('Main isolate alive!'),
);
// 16 is the limit, as documented in #51254. Setting this to 15 allows the main isolate to keep running
for (int i = 0; i < 16; i++) {
Isolate.spawn((_) {
while (true) {
print('Isolate $i alive');
// Any synchronous function call that blocks the isolate. Here are some examples:
// Process.runSync('sleep', ['1']);
// File.fromUri(Platform.script).readAsBytesSync();
// Directory.current.listSync();
// Directory.current.createSync(recursive: true);
sleep(Duration(seconds: 1));
}
}, null);
}
}I would expect these functions to call Dart_ExitIsolate (or some internal equivalent) before running the blocking call (whether it be poll in the case of Process.runSync, sleep in the case of sleep or any other blocking native call) in order to allow other isolates in the isolate group to run. Maybe this could also be done when calling into FFI isLeaf: true calls?
I don't know of any other blocking functions in the SDK other than dart:io's, but if there are some it goes without saying the same should be done there.
Tested on dart version 3.7.0-132.0.dev and 73adec7