Skip to content

Commit

Permalink
[io] Exit the isolate during Process.runSync and sleep.
Browse files Browse the repository at this point in the history
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: #51254
Bug: #54687
Bug: #57119
Change-Id: Ic04bbaa7f482d533ad0ecf2c6da17ea9f00c264e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398927
Reviewed-by: Alexander Aprelev <[email protected]>
Commit-Queue: Ryan Macnak <[email protected]>
  • Loading branch information
rmacnak-google authored and Commit Queue committed Dec 5, 2024
1 parent 6f992ae commit 322baef
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 0 deletions.
14 changes: 14 additions & 0 deletions runtime/bin/dartutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions runtime/bin/process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
2 changes: 2 additions & 0 deletions runtime/bin/process_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions runtime/bin/process_macos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions runtime/bin/process_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
@@ -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++;
}
}
Original file line number Diff line number Diff line change
@@ -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++;
}
}

0 comments on commit 322baef

Please sign in to comment.