1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-08 12:06:26 +00:00

[vm] Don't forget an isolate is shutting down when processing a resume command.

Cf. 4443d2d561

TEST=ci
Bug: b/271314180
Change-Id: I28553ef064ee603c076b69f5b887028bb81967ca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292460
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
This commit is contained in:
Ryan Macnak 2023-04-03 20:52:36 +00:00 committed by Commit Queue
parent 0fcdb66666
commit 70bbee75de
2 changed files with 83 additions and 1 deletions

View File

@ -0,0 +1,80 @@
// Copyright (c) 2023, 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.
// VMOptions=--pause-isolate-on-exit --enable-vm-service=0 --disable-service-auth-codes
// See b/271314180.
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'dart:isolate';
final childCount = 4;
child(i) {
print("Child $i");
// Paused-at-exit.
}
main() {
for (var i = 0; i < childCount; i++) {
Isolate.spawn(child, i);
}
Isolate.spawn(resumer, null);
print("Parent");
// Paused-at-exit.
}
get(String method, Map<String, dynamic> arguments) async {
var info = await Service.getInfo();
var uri = info.serverUri!.replace(path: method, queryParameters: arguments);
var client = new HttpClient();
try {
var request = await client.getUrl(uri);
var response = await request.close();
var string = await response.transform(utf8.decoder).join();
return jsonDecode(string);
} finally {
client.close();
}
}
resumer(_) async {
try {
// Wait for the main isolate and children to all be paused at exit.
var paused = <String>[];
do {
paused.clear();
var vm = (await get("getVM", {}))["result"];
for (var isolate in vm["isolates"]) {
var id = isolate["id"];
isolate = (await get("getIsolate", {"isolateId": id}))["result"];
if ((isolate["pauseEvent"] != null) &&
(isolate["pauseEvent"]["kind"] == "PauseExit")) {
paused.add(id);
}
}
} while (paused.length != childCount + 1);
// Resume the main isolate and children. When the main isolate resumes, it
// will exit and trigger VM shutdown. The VM shutdown will send the OOB kill
// message to children and so race with the resume message. No matter how
// the race resolves, the children should exit and the VM shutdown should
// not hang with
// Attempt:138 waiting for isolate child to check in
// ...
for (var id in paused) {
get("resume", {"isolateId": id}).then((v) => print(v));
}
} catch (e, st) {
print(e);
print(st);
rethrow;
}
// This isolate itself will be paused-at-exit with no resume message coming,
// but should exit because of the VM shutdown.
}

View File

@ -424,7 +424,9 @@ void MessageHandler::TaskCallback() {
return;
} else {
PausedOnExitLocked(&ml, false);
status = remembered_paused_on_exit_status_;
if (status != kShutdown) {
status = remembered_paused_on_exit_status_;
}
}
}
#endif // !defined(PRODUCT)