未验证 提交 4f6462bc 编写于 作者: G gaaclarke 提交者: GitHub

Made sure not to delete handles of dart objects if the isolate has been deleted (#25506)

上级 dade70a0
...@@ -203,6 +203,12 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate( ...@@ -203,6 +203,12 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRunningRootIsolate(
return isolate; return isolate;
} }
void DartIsolate::SpawnIsolateShutdownCallback(
std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
std::shared_ptr<DartIsolate>* isolate_data) {
DartIsolate::DartIsolateShutdownCallback(isolate_group_data, isolate_data);
}
std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate( std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
const Settings& settings, const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot, fml::RefPtr<const DartSnapshot> isolate_snapshot,
...@@ -267,7 +273,9 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate( ...@@ -267,7 +273,9 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
return Dart_CreateIsolateInGroup( return Dart_CreateIsolateInGroup(
/*group_member=*/spawning_isolate->isolate(), /*group_member=*/spawning_isolate->isolate(),
/*name=*/(*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(), /*name=*/(*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(),
/*shutdown_callback=*/nullptr, /*shutdown_callback=*/
reinterpret_cast<Dart_IsolateShutdownCallback>(
DartIsolate::SpawnIsolateShutdownCallback),
/*cleanup_callback=*/nullptr, /*cleanup_callback=*/nullptr,
/*child_isolate_data=*/isolate_data, /*child_isolate_data=*/isolate_data,
/*error=*/error); /*error=*/error);
......
...@@ -552,6 +552,10 @@ class DartIsolate : public UIDartState { ...@@ -552,6 +552,10 @@ class DartIsolate : public UIDartState {
// |Dart_DeferredLoadHandler| // |Dart_DeferredLoadHandler|
static Dart_Handle OnDartLoadLibrary(intptr_t loading_unit_id); static Dart_Handle OnDartLoadLibrary(intptr_t loading_unit_id);
static void SpawnIsolateShutdownCallback(
std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
std::shared_ptr<DartIsolate>* isolate_data);
FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate); FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate);
}; };
......
...@@ -153,6 +153,7 @@ TEST_F(DartIsolateTest, SpawnIsolate) { ...@@ -153,6 +153,7 @@ TEST_F(DartIsolateTest, SpawnIsolate) {
} }
ASSERT_TRUE(spawn->Shutdown()); ASSERT_TRUE(spawn->Shutdown());
ASSERT_TRUE(spawn->IsShuttingDown());
ASSERT_TRUE(root_isolate->Shutdown()); ASSERT_TRUE(root_isolate->Shutdown());
} }
......
...@@ -13,12 +13,25 @@ AutoIsolateShutdown::AutoIsolateShutdown(std::shared_ptr<DartIsolate> isolate, ...@@ -13,12 +13,25 @@ AutoIsolateShutdown::AutoIsolateShutdown(std::shared_ptr<DartIsolate> isolate,
: isolate_(std::move(isolate)), runner_(std::move(runner)) {} : isolate_(std::move(isolate)), runner_(std::move(runner)) {}
AutoIsolateShutdown::~AutoIsolateShutdown() { AutoIsolateShutdown::~AutoIsolateShutdown() {
if (!isolate_->IsShuttingDown()) {
Shutdown();
}
fml::AutoResetWaitableEvent latch;
fml::TaskRunner::RunNowOrPostTask(runner_,
[isolate = std::move(isolate_), &latch]() {
// Delete isolate on thread.
latch.Signal();
});
latch.Wait();
}
void AutoIsolateShutdown::Shutdown() {
if (!IsValid()) { if (!IsValid()) {
return; return;
} }
fml::AutoResetWaitableEvent latch; fml::AutoResetWaitableEvent latch;
fml::TaskRunner::RunNowOrPostTask( fml::TaskRunner::RunNowOrPostTask(
runner_, [isolate = std::move(isolate_), &latch]() { runner_, [isolate = isolate_.get(), &latch]() {
if (!isolate->Shutdown()) { if (!isolate->Shutdown()) {
FML_LOG(ERROR) << "Could not shutdown isolate."; FML_LOG(ERROR) << "Could not shutdown isolate.";
FML_CHECK(false); FML_CHECK(false);
......
...@@ -30,6 +30,8 @@ class AutoIsolateShutdown { ...@@ -30,6 +30,8 @@ class AutoIsolateShutdown {
[[nodiscard]] bool RunInIsolateScope(std::function<bool(void)> closure); [[nodiscard]] bool RunInIsolateScope(std::function<bool(void)> closure);
void Shutdown();
DartIsolate* get() { DartIsolate* get() {
FML_CHECK(isolate_); FML_CHECK(isolate_);
return isolate_.get(); return isolate_.get();
......
...@@ -43,12 +43,19 @@ void DartPersistentValue::Clear() { ...@@ -43,12 +43,19 @@ void DartPersistentValue::Clear() {
return; return;
} }
if (Dart_CurrentIsolateGroup()) { /// TODO(80155): Remove the handle even if the isolate is shutting down. This
Dart_DeletePersistentHandle(value_); /// may cause memory to stick around until the isolate group is destroyed.
} else { /// Without this branch, if DartState::IsShuttingDown == true, this code will
DartIsolateScope scope(dart_state->isolate()); /// crash when binding the isolate.
Dart_DeletePersistentHandle(value_); if (!dart_state->IsShuttingDown()) {
if (Dart_CurrentIsolateGroup()) {
Dart_DeletePersistentHandle(value_);
} else {
DartIsolateScope scope(dart_state->isolate());
Dart_DeletePersistentHandle(value_);
}
} }
dart_state_.reset(); dart_state_.reset();
value_ = nullptr; value_ = nullptr;
} }
......
...@@ -15,6 +15,7 @@ executable("tonic_unittests") { ...@@ -15,6 +15,7 @@ executable("tonic_unittests") {
public_configs = [ "//flutter:export_dynamic_symbols" ] public_configs = [ "//flutter:export_dynamic_symbols" ]
sources = [ sources = [
"dart_persistent_handle_unittest.cc",
"dart_state_unittest.cc", "dart_state_unittest.cc",
"dart_weak_persistent_handle_unittest.cc", "dart_weak_persistent_handle_unittest.cc",
] ]
......
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/testing/dart_isolate_runner.h"
#include "flutter/testing/fixture_test.h"
namespace flutter {
namespace testing {
class DartPersistentHandleTest : public FixtureTest {
public:
DartPersistentHandleTest()
: settings_(CreateSettingsForFixture()),
vm_(DartVMRef::Create(settings_)),
thread_(CreateNewThread()),
task_runners_(GetCurrentTestName(),
thread_,
thread_,
thread_,
thread_) {}
~DartPersistentHandleTest() = default;
[[nodiscard]] bool RunWithEntrypoint(const std::string& entrypoint) {
if (running_isolate_) {
return false;
}
auto isolate = RunDartCodeInIsolate(vm_, settings_, task_runners_,
entrypoint, {}, GetFixturesPath());
if (!isolate || isolate->get()->GetPhase() != DartIsolate::Phase::Running) {
return false;
}
running_isolate_ = std::move(isolate);
return true;
}
protected:
Settings settings_;
DartVMRef vm_;
std::unique_ptr<AutoIsolateShutdown> running_isolate_;
fml::RefPtr<fml::TaskRunner> thread_;
TaskRunners task_runners_;
FML_DISALLOW_COPY_AND_ASSIGN(DartPersistentHandleTest);
};
TEST_F(DartPersistentHandleTest, ClearAfterShutdown) {
auto persistent_value = tonic::DartPersistentValue();
fml::AutoResetWaitableEvent event;
AddNativeCallback("GiveObjectToNative",
CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
auto handle = Dart_GetNativeArgument(args, 0);
auto dart_state = tonic::DartState::Current();
ASSERT_TRUE(dart_state);
ASSERT_TRUE(tonic::DartState::Current());
persistent_value.Set(dart_state, handle);
event.Signal();
}));
ASSERT_TRUE(RunWithEntrypoint("callGiveObjectToNative"));
event.Wait();
running_isolate_->Shutdown();
fml::AutoResetWaitableEvent clear;
task_runners_.GetUITaskRunner()->PostTask([&] {
persistent_value.Clear();
clear.Signal();
});
clear.Wait();
}
} // namespace testing
} // namespace flutter
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
namespace flutter { namespace flutter {
namespace testing { namespace testing {
namespace {
void NopFinalizer(void* isolate_callback_data, void* peer) {}
} // namespace
class DartWeakPersistentHandle : public FixtureTest { class DartWeakPersistentHandle : public FixtureTest {
public: public:
DartWeakPersistentHandle() DartWeakPersistentHandle()
...@@ -45,8 +49,6 @@ class DartWeakPersistentHandle : public FixtureTest { ...@@ -45,8 +49,6 @@ class DartWeakPersistentHandle : public FixtureTest {
FML_DISALLOW_COPY_AND_ASSIGN(DartWeakPersistentHandle); FML_DISALLOW_COPY_AND_ASSIGN(DartWeakPersistentHandle);
}; };
void NopFinalizer(void* isolate_callback_data, void* peer) {}
TEST_F(DartWeakPersistentHandle, ClearImmediately) { TEST_F(DartWeakPersistentHandle, ClearImmediately) {
auto weak_persistent_value = tonic::DartWeakPersistentValue(); auto weak_persistent_value = tonic::DartWeakPersistentValue();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册