b759d096cb
Fixes https://github.com/dart-lang/sdk/issues/61287 TEST=ffi/isolate_group_bound_captured_local_test Change-Id: I9dc1e8aaf9e99d8ec9ad730cf1cd89ae3b4ed148 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/444923 Commit-Queue: Alexander Aprelev <aam@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
145 lines
3.7 KiB
Dart
145 lines
3.7 KiB
Dart
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
//
|
|
// Tests IsolateGroup.runSync - what works, what doesn't.
|
|
//
|
|
// VMOptions=--experimental-shared-data
|
|
// VMOptions=--experimental-shared-data --use-slow-path
|
|
// VMOptions=--experimental-shared-data --use-slow-path --stacktrace-every=100
|
|
// VMOptions=--experimental-shared-data --dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects
|
|
// VMOptions=--experimental-shared-data --test_il_serialization
|
|
// VMOptions=--experimental-shared-data --profiler --profile_vm=true
|
|
// VMOptions=--experimental-shared-data --profiler --profile_vm=false
|
|
|
|
import 'dart:async';
|
|
import 'dart:concurrent';
|
|
import 'dart:ffi';
|
|
import 'dart:io';
|
|
import 'dart:isolate';
|
|
|
|
import 'package:dart_internal/isolate_group.dart' show IsolateGroup;
|
|
import "package:expect/async_helper.dart";
|
|
import "package:expect/expect.dart";
|
|
import 'package:ffi/ffi.dart';
|
|
|
|
@pragma('vm:shared')
|
|
late final Mutex mutex;
|
|
|
|
@pragma('vm:shared')
|
|
late final String shared_late_final_string = () {
|
|
return "${int.parse('123') + 42}";
|
|
}();
|
|
|
|
@pragma('vm:shared')
|
|
late final String shared_late_final_throw = () {
|
|
throw "${int.parse('123') + 42}";
|
|
}();
|
|
|
|
@pragma('vm:shared')
|
|
late final String foo = () {
|
|
return "${int.parse('123') + 42}";
|
|
}();
|
|
|
|
testInitStrings() async {
|
|
const int nWorkers = 100;
|
|
mutex = Mutex();
|
|
final rp = ReceivePort();
|
|
final rpExitAndErrors = ReceivePort()
|
|
..listen((e) {
|
|
print('e: $e');
|
|
});
|
|
final completer = Completer();
|
|
int counter = 0;
|
|
rp.listen((data) {
|
|
counter++;
|
|
print('got $data, counter: $counter');
|
|
Expect.equals("165", data);
|
|
if (counter == nWorkers) {
|
|
completer.complete(data);
|
|
}
|
|
});
|
|
for (int i = 0; i < nWorkers; i++) {
|
|
Isolate.spawn(
|
|
(sendPort) {
|
|
@pragma('vm:shared')
|
|
final sp = sendPort;
|
|
IsolateGroup.runSync(() {
|
|
sp.send(shared_late_final_string);
|
|
});
|
|
},
|
|
rp.sendPort,
|
|
onExit: rpExitAndErrors.sendPort,
|
|
onError: rpExitAndErrors.sendPort,
|
|
);
|
|
print("spawned isolate #$i");
|
|
}
|
|
Expect.equals("165", await completer.future);
|
|
rpExitAndErrors.close();
|
|
rp.close();
|
|
}
|
|
|
|
testInitThrows() async {
|
|
const int nWorkers = 100;
|
|
final rp = ReceivePort();
|
|
int exitCounter = 0;
|
|
final completer = Completer();
|
|
ReceivePort rpExits = ReceivePort()
|
|
..listen((e) {
|
|
exitCounter++;
|
|
print('exitCounter: $exitCounter, exit: $e');
|
|
if (exitCounter == nWorkers) {
|
|
completer.complete(true);
|
|
}
|
|
});
|
|
int errorCounter = 0;
|
|
ReceivePort rpErrors = ReceivePort()
|
|
..listen((e) {
|
|
errorCounter++;
|
|
Expect.equals("165", e[0]);
|
|
print('errorCounter: $errorCounter, error: $e');
|
|
});
|
|
for (int i = 0; i < nWorkers; i++) {
|
|
Isolate.spawn(
|
|
(sendPort) {
|
|
@pragma('vm:shared')
|
|
final sp = sendPort;
|
|
IsolateGroup.runSync(() {
|
|
try {
|
|
sp.send(shared_late_final_throw);
|
|
} catch (e) {
|
|
Expect.equals("165", e);
|
|
rethrow;
|
|
}
|
|
});
|
|
},
|
|
rp.sendPort,
|
|
onExit: rpExits.sendPort,
|
|
onError: rpErrors.sendPort,
|
|
);
|
|
print("spawned isolate #$i");
|
|
}
|
|
await completer.future;
|
|
Expect.equals(nWorkers, errorCounter);
|
|
rpErrors.close();
|
|
rpExits.close();
|
|
rp.close();
|
|
}
|
|
|
|
@pragma('vm:shared')
|
|
late final String foo_bar = () {
|
|
return "${int.parse('123') + 42} $foo";
|
|
}();
|
|
|
|
testNestedInitCall() {
|
|
Expect.equals("165 165", foo_bar);
|
|
}
|
|
|
|
main() async {
|
|
asyncStart();
|
|
await testInitStrings();
|
|
await testInitThrows();
|
|
testNestedInitCall();
|
|
asyncEnd();
|
|
}
|