Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit bc8f6aa

Browse files
committed
Create root isolate asynchronously
1 parent 39a3193 commit bc8f6aa

File tree

2 files changed

+82
-53
lines changed

2 files changed

+82
-53
lines changed

runtime/runtime_controller.cc

Lines changed: 78 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -46,65 +46,92 @@ RuntimeController::RuntimeController(
4646
platform_data_(std::move(p_platform_data)),
4747
isolate_create_callback_(p_isolate_create_callback),
4848
isolate_shutdown_callback_(p_isolate_shutdown_callback),
49-
persistent_isolate_data_(std::move(p_persistent_isolate_data)) {
50-
// Create the root isolate as soon as the runtime controller is initialized.
49+
persistent_isolate_data_(std::move(p_persistent_isolate_data)),
50+
weak_factory_(this) {
51+
// Create the root isolate as soon as the runtime controller is initialized,
52+
// but not using a synchronous way to avoid blocking the platform thread a
53+
// long time as it is waiting while creating `Shell` on that platform thread.
5154
// It will be run at a later point when the engine provides a run
5255
// configuration and then runs the isolate.
53-
auto strong_root_isolate =
54-
DartIsolate::CreateRootIsolate(
55-
vm_->GetVMData()->GetSettings(), //
56-
isolate_snapshot_, //
57-
task_runners_, //
58-
std::make_unique<PlatformConfiguration>(this), //
59-
snapshot_delegate_, //
60-
io_manager_, //
61-
unref_queue_, //
62-
image_decoder_, //
63-
p_advisory_script_uri, //
64-
p_advisory_script_entrypoint, //
65-
nullptr, //
66-
isolate_create_callback_, //
67-
isolate_shutdown_callback_ //
68-
)
69-
.lock();
70-
71-
FML_CHECK(strong_root_isolate) << "Could not create root isolate.";
72-
73-
// The root isolate ivar is weak.
74-
root_isolate_ = strong_root_isolate;
75-
76-
strong_root_isolate->SetReturnCodeCallback([this](uint32_t code) {
77-
root_isolate_return_code_ = {true, code};
78-
});
79-
80-
if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) {
81-
tonic::DartState::Scope scope(strong_root_isolate);
82-
platform_configuration->DidCreateIsolate();
83-
if (!FlushRuntimeStateToIsolate()) {
84-
FML_DLOG(ERROR) << "Could not setup initial isolate state.";
85-
}
86-
} else {
87-
FML_DCHECK(false) << "RuntimeController created without window binding.";
88-
}
89-
90-
FML_DCHECK(Dart_CurrentIsolate() == nullptr);
56+
root_isolate_future_ =
57+
std::async(std::launch::deferred, [self = weak_factory_.GetWeakPtr()]() {
58+
if (!self) {
59+
return std::weak_ptr<DartIsolate>();
60+
}
61+
62+
auto strong_root_isolate =
63+
DartIsolate::CreateRootIsolate(
64+
self->vm_->GetVMData()->GetSettings(), //
65+
self->isolate_snapshot_, //
66+
self->task_runners_, //
67+
std::make_unique<PlatformConfiguration>(self.get()), //
68+
self->snapshot_delegate_, //
69+
self->io_manager_, //
70+
self->unref_queue_, //
71+
self->image_decoder_, //
72+
self->advisory_script_uri_, //
73+
self->advisory_script_entrypoint_, //
74+
nullptr, //
75+
self->isolate_create_callback_, //
76+
self->isolate_shutdown_callback_ //
77+
)
78+
.lock();
79+
80+
FML_CHECK(strong_root_isolate) << "Could not create root isolate.";
81+
82+
strong_root_isolate->SetReturnCodeCallback([self](uint32_t code) {
83+
if (!self) {
84+
return;
85+
}
86+
87+
self->root_isolate_return_code_ = {true, code};
88+
});
89+
90+
if (auto* platform_configuration =
91+
self->GetPlatformConfigurationIfAvailable()) {
92+
tonic::DartState::Scope scope(strong_root_isolate);
93+
platform_configuration->DidCreateIsolate();
94+
if (!self->FlushRuntimeStateToIsolate()) {
95+
FML_DLOG(ERROR) << "Could not setup initial isolate state.";
96+
}
97+
} else {
98+
FML_DCHECK(false)
99+
<< "RuntimeController created without window binding.";
100+
}
101+
102+
FML_DCHECK(Dart_CurrentIsolate() == nullptr);
103+
104+
return std::weak_ptr<DartIsolate>(strong_root_isolate);
105+
});
106+
107+
task_runners_.GetUITaskRunner()->PostTask(
108+
[self = weak_factory_.GetWeakPtr()]() {
109+
if (!self) {
110+
return;
111+
}
112+
113+
self->root_isolate_future_.wait();
114+
});
91115
}
92116

93117
RuntimeController::~RuntimeController() {
94118
FML_DCHECK(Dart_CurrentIsolate() == nullptr);
95-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
119+
if (!root_isolate_future_.valid()) {
120+
return;
121+
}
122+
std::shared_ptr<DartIsolate> root_isolate = root_isolate_future_.get().lock();
96123
if (root_isolate) {
97124
root_isolate->SetReturnCodeCallback(nullptr);
98125
auto result = root_isolate->Shutdown();
99126
if (!result) {
100127
FML_DLOG(ERROR) << "Could not shutdown the root isolate.";
101128
}
102-
root_isolate_ = {};
129+
root_isolate_future_.get() = {};
103130
}
104131
}
105132

106-
bool RuntimeController::IsRootIsolateRunning() const {
107-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
133+
bool RuntimeController::IsRootIsolateRunning() {
134+
std::shared_ptr<DartIsolate> root_isolate = root_isolate_future_.get().lock();
108135
if (root_isolate) {
109136
return root_isolate->GetPhase() == DartIsolate::Phase::Running;
110137
}
@@ -230,7 +257,7 @@ bool RuntimeController::ReportTimings(std::vector<int64_t> timings) {
230257
}
231258

232259
bool RuntimeController::NotifyIdle(int64_t deadline) {
233-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
260+
std::shared_ptr<DartIsolate> root_isolate = root_isolate_future_.get().lock();
234261
if (!root_isolate) {
235262
return false;
236263
}
@@ -287,7 +314,7 @@ bool RuntimeController::DispatchSemanticsAction(int32_t id,
287314

288315
PlatformConfiguration*
289316
RuntimeController::GetPlatformConfigurationIfAvailable() {
290-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
317+
std::shared_ptr<DartIsolate> root_isolate = root_isolate_future_.get().lock();
291318
return root_isolate ? root_isolate->platform_configuration() : nullptr;
292319
}
293320

@@ -349,17 +376,17 @@ RuntimeController::ComputePlatformResolvedLocale(
349376
}
350377

351378
Dart_Port RuntimeController::GetMainPort() {
352-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
379+
std::shared_ptr<DartIsolate> root_isolate = root_isolate_future_.get().lock();
353380
return root_isolate ? root_isolate->main_port() : ILLEGAL_PORT;
354381
}
355382

356383
std::string RuntimeController::GetIsolateName() {
357-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
384+
std::shared_ptr<DartIsolate> root_isolate = root_isolate_future_.get().lock();
358385
return root_isolate ? root_isolate->debug_name() : "";
359386
}
360387

361388
bool RuntimeController::HasLivePorts() {
362-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
389+
std::shared_ptr<DartIsolate> root_isolate = root_isolate_future_.get().lock();
363390
if (!root_isolate) {
364391
return false;
365392
}
@@ -368,12 +395,12 @@ bool RuntimeController::HasLivePorts() {
368395
}
369396

370397
tonic::DartErrorHandleType RuntimeController::GetLastError() {
371-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
398+
std::shared_ptr<DartIsolate> root_isolate = root_isolate_future_.get().lock();
372399
return root_isolate ? root_isolate->GetLastError() : tonic::kNoError;
373400
}
374401

375402
std::weak_ptr<DartIsolate> RuntimeController::GetRootIsolate() {
376-
return root_isolate_;
403+
return root_isolate_future_.get();
377404
}
378405

379406
std::pair<bool, uint32_t> RuntimeController::GetRootIsolateReturnCode() {

runtime/runtime_controller.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef FLUTTER_RUNTIME_RUNTIME_CONTROLLER_H_
66
#define FLUTTER_RUNTIME_RUNTIME_CONTROLLER_H_
77

8+
#include <future>
89
#include <memory>
910
#include <vector>
1011

@@ -340,7 +341,7 @@ class RuntimeController final : public PlatformConfigurationClient {
340341
///
341342
/// @return True if root isolate running, False otherwise.
342343
///
343-
bool IsRootIsolateRunning() const;
344+
bool IsRootIsolateRunning();
344345

345346
//----------------------------------------------------------------------------
346347
/// @brief Dispatch the specified platform message to running root
@@ -467,11 +468,12 @@ class RuntimeController final : public PlatformConfigurationClient {
467468
std::string advisory_script_entrypoint_;
468469
std::function<void(int64_t)> idle_notification_callback_;
469470
PlatformData platform_data_;
470-
std::weak_ptr<DartIsolate> root_isolate_;
471+
std::future<std::weak_ptr<DartIsolate>> root_isolate_future_;
471472
std::pair<bool, uint32_t> root_isolate_return_code_ = {false, 0};
472473
const fml::closure isolate_create_callback_;
473474
const fml::closure isolate_shutdown_callback_;
474475
std::shared_ptr<const fml::Mapping> persistent_isolate_data_;
476+
fml::WeakPtrFactory<RuntimeController> weak_factory_;
475477

476478
PlatformConfiguration* GetPlatformConfigurationIfAvailable();
477479

0 commit comments

Comments
 (0)