[io] Exit the isolate during Process.runSync and sleep.

This prevents such an isolate from occupying one of the limited number of mutator slots and blocking other isolates in the same group from running.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/51254
Bug: https://github.com/dart-lang/sdk/issues/54687
Bug: https://github.com/dart-lang/sdk/issues/57119
Change-Id: Ic04bbaa7f482d533ad0ecf2c6da17ea9f00c264e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398927
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak
2024-12-05 00:16:38 +00:00
committed by Commit Queue
parent 6f992aea0d
commit 322baef3e1
7 changed files with 72 additions and 0 deletions
+14
View File
@@ -651,6 +651,20 @@ class ScopedBlockingCall {
DISALLOW_COPY_AND_ASSIGN(ScopedBlockingCall);
};
// Remove once we remove the limitation on the number of running mutators.
// https://github.com/dart-lang/sdk/issues/54687
class LeaveIsolateScope {
public:
LeaveIsolateScope() : isolate_(Dart_CurrentIsolate()) { Dart_ExitIsolate(); }
~LeaveIsolateScope() { Dart_EnterIsolate(isolate_); }
private:
Dart_Isolate isolate_;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(LeaveIsolateScope);
};
struct MagicNumberData {
static constexpr intptr_t kMaxLength = 8;
+2
View File
@@ -285,6 +285,8 @@ void FUNCTION_NAME(Process_Sleep)(Dart_NativeArguments args) {
int64_t milliseconds = 0;
// Ignore result if passing invalid argument and just set exit code to 0.
DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &milliseconds);
LeaveIsolateScope leave_isolate;
TimerUtils::Sleep(milliseconds);
}
+2
View File
@@ -849,6 +849,8 @@ bool Process::Wait(intptr_t pid,
int alive = 3;
while (alive > 0) {
LeaveIsolateScope leave_isolate;
// Blocking call waiting for events from the child process.
if (TEMP_FAILURE_RETRY(poll(fds, alive, -1)) <= 0) {
return CloseProcessBuffers(fds, alive);
+2
View File
@@ -826,6 +826,8 @@ bool Process::Wait(intptr_t pid,
int alive = 3;
while (alive > 0) {
LeaveIsolateScope leave_isolate;
// Blocking call waiting for events from the child process.
if (TEMP_FAILURE_RETRY(poll(fds, alive, -1)) <= 0) {
return CloseProcessBuffers(fds, alive);
+2
View File
@@ -828,6 +828,8 @@ bool Process::Wait(intptr_t pid,
// Continue until all handles are closed.
int alive = kHandles;
while (alive > 0) {
LeaveIsolateScope leave_isolate;
// Blocking call waiting for events from the child process.
DWORD wait_result = WaitForMultipleObjects(alive, events, FALSE, INFINITE);
@@ -0,0 +1,25 @@
// Copyright (c) 2024, 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 "dart:isolate";
import "dart:io";
child(replyPort) {
replyPort.send(null);
Process.runSync("sleep", ["3600"]);
}
main() async {
var pending = 0;
var port;
port = new RawReceivePort((msg) {
pending--;
if (pending == 0) exit(0);
});
for (var i = 0; i < 20; i++) {
Isolate.spawn(child, port.sendPort);
pending++;
}
}
@@ -0,0 +1,25 @@
// Copyright (c) 2024, 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 "dart:isolate";
import "dart:io";
child(replyPort) {
replyPort.send(null);
sleep(Duration(minutes: 60));
}
main() async {
var pending = 0;
var port;
port = new RawReceivePort((msg) {
pending--;
if (pending == 0) exit(0);
});
for (var i = 0; i < 20; i++) {
Isolate.spawn(child, port.sendPort);
pending++;
}
}