fc750ac8e0
Snapshots are now generally signed Mach-O dylibs loaded by dlopen, instead of ELF files mapped executable by the VM's loader. TEST=ci Change-Id: Id19877bed0bd0282b320f070904a848b0c076a54 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505200 Reviewed-by: Tess Strickland <sstrickl@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
119 lines
2.6 KiB
Dart
119 lines
2.6 KiB
Dart
// Copyright (c) 2021, 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.
|
|
|
|
import 'package:expect/expect.dart';
|
|
|
|
import 'reload_utils.dart';
|
|
|
|
final N = 5;
|
|
|
|
main() async {
|
|
if (!currentVmSupportsReload) return;
|
|
|
|
await withTempDir("reload-active-stack", (String tempDir) async {
|
|
final dills = await generateDills(tempDir, dartTestFile(N));
|
|
final reloader = await launchOn(dills[0]);
|
|
|
|
await reloader.waitUntilStdoutContainsN('entering ready loop', N);
|
|
|
|
final reloadResult1 = await reloader.reload(dills[1]);
|
|
Expect.equals('ReloadReport', reloadResult1['type']);
|
|
Expect.equals(true, reloadResult1['success']);
|
|
|
|
await reloader.waitUntilStdoutContainsN('entering done loop', N);
|
|
|
|
final reloadResult2 = await reloader.reload(dills[2]);
|
|
Expect.equals('ReloadReport', reloadResult2['type']);
|
|
Expect.equals(true, reloadResult2['success']);
|
|
|
|
final int exitCode = await reloader.close();
|
|
Expect.equals(0, exitCode);
|
|
});
|
|
}
|
|
|
|
String dartTestFile(int N) =>
|
|
'''
|
|
import 'dart:async';
|
|
import 'dart:isolate';
|
|
|
|
import 'package:expect/expect.dart';
|
|
|
|
const int N = $N;
|
|
|
|
Future main() async {
|
|
final done = ReceivePort();
|
|
final errors = ReceivePort();
|
|
for (int i = 0; i < N; ++i) {
|
|
await Isolate.spawn(child, i,
|
|
onExit: done.sendPort, onError: errors.sendPort);
|
|
}
|
|
|
|
final allErrors = [];
|
|
errors.listen((e) {
|
|
print('error: \$e');
|
|
allErrors.add(e);
|
|
});
|
|
|
|
final si = StreamIterator(done);
|
|
for (int i = 0; i < N; ++i) {
|
|
Expect.isTrue(await si.moveNext());
|
|
print('got exit');
|
|
}
|
|
await si.cancel();
|
|
|
|
errors.close();
|
|
Expect.equals(0, allErrors.length);
|
|
}
|
|
|
|
void child(int index) {
|
|
bool isReady = false;
|
|
ensureReady() {
|
|
if (!isReady) {
|
|
print('[child-\$index] entering ready loop');
|
|
isReady = true;
|
|
}
|
|
}
|
|
|
|
bool isDone = false;
|
|
ensureDone() {
|
|
if (!isDone) {
|
|
print('[child-\$index] entering done loop');
|
|
isDone = true;
|
|
}
|
|
}
|
|
|
|
try {
|
|
while (true) {
|
|
ensureReady();
|
|
insideInfiniteLoop();
|
|
}
|
|
} on Done {
|
|
print('Got infinite loop abortion');
|
|
}
|
|
|
|
try {
|
|
while (true) {
|
|
ensureDone();
|
|
insideShutdownLoop();
|
|
}
|
|
} on Done {
|
|
print('Got shutdown');
|
|
}
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
void insideInfiniteLoop() {
|
|
print('throwing Done'); // @include-in-reload-1
|
|
throw Done(); // @include-in-reload-1
|
|
}
|
|
|
|
@pragma('vm:never-inline')
|
|
void insideShutdownLoop() {
|
|
print('throwing Done 2'); // @include-in-reload-2
|
|
throw Done(); // @include-in-reload-2
|
|
}
|
|
|
|
class Done {}
|
|
''';
|