Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions common/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ struct Settings {
// call is made.
fml::closure root_isolate_shutdown_callback;
fml::closure isolate_shutdown_callback;
// A callback made in the isolate scope of the service isolate when it is
// launched. Care must be taken to ensure that callers are assigning callbacks
// to the settings object used to launch the VM. If an existing VM is used to
// launch an isolate using these settings, the callback will be ignored as the
// service isolate has already been launched. Also, this callback will only be
// made in the modes in which the service isolate is eligible for launch
// (debug and profile).
fml::closure service_isolate_create_callback;
// The callback made on the UI thread in an isolate scope when the engine
// detects that the framework is idle. The VM also uses this time to perform
// tasks suitable when idling. Due to this, embedders are still advised to be
Expand Down
12 changes: 12 additions & 0 deletions runtime/dart_isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,14 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(

flags->load_vmservice_library = true;

#if (FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG)
// TODO(68663): The service isolate in debug mode is always launched without
// sound null safety. Fix after the isolate snapshot data is created with the
// right flags.
flags->null_safety =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be a little more safe if we guard this code as
#if (FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG)
vm_data->GetIsolateSnapshot()->....
#endif

The reason being I feel the VM may hit an assert if a null value is passed for the script_uri.
Once we fix the VM to do the right thing we can adjust this code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I added a TODO for the fix. PTAL.

vm_data->GetIsolateSnapshot()->IsNullSafetyEnabled(nullptr);
#endif

std::weak_ptr<DartIsolate> weak_service_isolate =
DartIsolate::CreateRootIsolate(
vm_data->GetSettings(), // settings
Expand Down Expand Up @@ -739,6 +747,10 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
return nullptr;
}

if (auto callback = vm_data->GetSettings().service_isolate_create_callback) {
callback();
}

if (auto service_protocol = DartVMRef::GetServiceProtocol()) {
service_protocol->ToggleHooks(true);
} else {
Expand Down
54 changes: 54 additions & 0 deletions runtime/dart_isolate_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -321,5 +321,59 @@ TEST_F(DartIsolateTest, CanRecieveArguments) {
Wait();
}

TEST_F(DartIsolateTest, CanCreateServiceIsolate) {
#if (FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_DEBUG) && \
(FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_PROFILE)
GTEST_SKIP();
#endif
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
fml::AutoResetWaitableEvent service_isolate_latch;
auto settings = CreateSettingsForFixture();
settings.enable_observatory = true;
settings.observatory_port = 0;
settings.observatory_host = "127.0.0.1";
settings.enable_service_port_fallback = true;
settings.service_isolate_create_callback = [&service_isolate_latch]() {
service_isolate_latch.Signal();
};
auto vm_ref = DartVMRef::Create(settings);
ASSERT_TRUE(vm_ref);
auto vm_data = vm_ref.GetVMData();
ASSERT_TRUE(vm_data);
TaskRunners task_runners(GetCurrentTestName(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner() //
);

auto isolate_configuration =
IsolateConfiguration::InferFromSettings(settings);
auto weak_isolate = DartIsolate::CreateRunningRootIsolate(
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // hint freed delegate
{}, // io manager
{}, // unref queue
{}, // image decoder
"main.dart", // advisory uri
"main", // advisory entrypoint,
DartIsolate::Flags{}, // flags
settings.isolate_create_callback, // isolate create callback
settings.isolate_shutdown_callback, // isolate shutdown callback
"main", // dart entrypoint
std::nullopt, // dart entrypoint library
std::move(isolate_configuration) // isolate configuration
);
auto root_isolate = weak_isolate.lock();
ASSERT_TRUE(root_isolate);
ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::Running);
service_isolate_latch.Wait();
ASSERT_TRUE(root_isolate->Shutdown());
}

} // namespace testing
} // namespace flutter