[vm/native_api] Ensure isolate is not available for duration of native port operations.

Follow-up to 5a98fe5564.

TEST=ci

Change-Id: I62269b713968f0d0e436d86b7d7b481fc5b52cc5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/501620
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Alexander Aprelev
2026-05-20 08:40:17 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 82a952f14a
commit 58047e7d94
2 changed files with 23 additions and 12 deletions
+19 -12
View File
@@ -1838,27 +1838,34 @@ class EnterIsolateGroupScope {
// operate on an individual isolate.
class NoActiveIsolateScope : public StackResource {
public:
NoActiveIsolateScope() : NoActiveIsolateScope(Thread::Current()) {}
explicit NoActiveIsolateScope(Thread* thread)
explicit NoActiveIsolateScope(bool allow_no_thread = false)
: NoActiveIsolateScope(Thread::Current(), allow_no_thread) {}
explicit NoActiveIsolateScope(Thread* thread, bool allow_no_thread = false)
: StackResource(thread), thread_(thread) {
outer_ = thread_->no_active_isolate_scope_;
saved_isolate_ = thread_->isolate_;
ASSERT(allow_no_thread || thread_ != nullptr);
if (thread_ != nullptr) {
outer_ = thread_->no_active_isolate_scope_;
saved_isolate_ = thread_->isolate_;
thread_->no_active_isolate_scope_ = this;
thread_->isolate_ = nullptr;
thread_->no_active_isolate_scope_ = this;
thread_->isolate_ = nullptr;
}
}
~NoActiveIsolateScope() {
ASSERT(thread_->isolate_ == nullptr);
thread_->isolate_ = saved_isolate_;
thread_->no_active_isolate_scope_ = outer_;
ASSERT(thread_ == nullptr || thread_->isolate_ == nullptr);
ASSERT(thread_ != nullptr || saved_isolate_ == nullptr);
if (thread_ != nullptr) {
thread_->isolate_ = saved_isolate_;
thread_->no_active_isolate_scope_ = outer_;
}
}
private:
friend class ActiveIsolateScope;
Thread* thread_;
Isolate* saved_isolate_;
NoActiveIsolateScope* outer_;
Thread* thread_ = nullptr;
Isolate* saved_isolate_ = nullptr;
NoActiveIsolateScope* outer_ = nullptr;
};
class ActiveIsolateScope : public StackResource {
+4
View File
@@ -89,6 +89,7 @@ Dart_NewConcurrentNativePort(const char* name,
}
ENTER_API_CALL_OR_RETURN(ILLEGAL_PORT);
NoActiveIsolateScope no_active_isolate(/*allow_no_thread=*/true);
NativeMessageHandler* nmh =
new NativeMessageHandler(name, handler, max_concurrency);
Dart_Port port_id = PortMap::CreatePort(nmh);
@@ -98,6 +99,7 @@ Dart_NewConcurrentNativePort(const char* name,
DART_EXPORT bool Dart_CloseNativePort(Dart_Port native_port_id) {
ENTER_API_CALL_OR_RETURN(false)
NoActiveIsolateScope no_active_isolate(/*allow_no_thread=*/true);
PortHandler* handler = nullptr;
const bool was_closed = PortMap::ClosePort(native_port_id, &handler);
if (was_closed) {
@@ -122,6 +124,8 @@ DART_EXPORT bool Dart_InvokeVMServiceMethod(uint8_t* request_json,
Isolate* isolate = Isolate::Current();
ASSERT(isolate == nullptr || !isolate->is_service_isolate());
NoActiveIsolateScope no_active_isolate(/*allow_no_thread=*/true);
// We only allow one isolate reload at a time. If this turns out to be on the
// critical path, we can change it to have a global datastructure which is
// mapping the reply ports to receive buffers.