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

Commit a265256

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

File tree

7 files changed

+120
-51
lines changed

7 files changed

+120
-51
lines changed

runtime/runtime_controller.cc

Lines changed: 85 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -46,48 +46,76 @@ 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+
create_and_config_root_isolate_ =
57+
std::async(std::launch::deferred, [self = weak_factory_.GetWeakPtr()]() {
58+
if (!self) {
59+
return;
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+
// The root isolate ivar is weak.
83+
self->root_isolate_ = strong_root_isolate;
84+
85+
strong_root_isolate->SetReturnCodeCallback([self](uint32_t code) {
86+
if (!self) {
87+
return;
88+
}
89+
90+
self->root_isolate_return_code_ = {true, code};
91+
});
92+
93+
if (auto* platform_configuration =
94+
self->GetPlatformConfigurationIfAvailable()) {
95+
tonic::DartState::Scope scope(strong_root_isolate);
96+
platform_configuration->DidCreateIsolate();
97+
if (!self->FlushRuntimeStateToIsolate()) {
98+
FML_DLOG(ERROR) << "Could not setup initial isolate state.";
99+
}
100+
} else {
101+
FML_DCHECK(false)
102+
<< "RuntimeController created without window binding.";
103+
}
104+
105+
FML_DCHECK(Dart_CurrentIsolate() == nullptr);
106+
107+
self->client_.OnRootIsolateCreated();
108+
return;
109+
});
110+
111+
task_runners_.GetUITaskRunner()->PostTask(
112+
[self = weak_factory_.GetWeakPtr()]() {
113+
if (!self) {
114+
return;
115+
}
116+
117+
self->GetRootIsolate();
118+
});
91119
}
92120

93121
RuntimeController::~RuntimeController() {
@@ -103,8 +131,8 @@ RuntimeController::~RuntimeController() {
103131
}
104132
}
105133

106-
bool RuntimeController::IsRootIsolateRunning() const {
107-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
134+
bool RuntimeController::IsRootIsolateRunning() {
135+
std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
108136
if (root_isolate) {
109137
return root_isolate->GetPhase() == DartIsolate::Phase::Running;
110138
}
@@ -230,7 +258,7 @@ bool RuntimeController::ReportTimings(std::vector<int64_t> timings) {
230258
}
231259

232260
bool RuntimeController::NotifyIdle(int64_t deadline) {
233-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
261+
std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
234262
if (!root_isolate) {
235263
return false;
236264
}
@@ -287,7 +315,7 @@ bool RuntimeController::DispatchSemanticsAction(int32_t id,
287315

288316
PlatformConfiguration*
289317
RuntimeController::GetPlatformConfigurationIfAvailable() {
290-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
318+
std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
291319
return root_isolate ? root_isolate->platform_configuration() : nullptr;
292320
}
293321

@@ -349,17 +377,17 @@ RuntimeController::ComputePlatformResolvedLocale(
349377
}
350378

351379
Dart_Port RuntimeController::GetMainPort() {
352-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
380+
std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
353381
return root_isolate ? root_isolate->main_port() : ILLEGAL_PORT;
354382
}
355383

356384
std::string RuntimeController::GetIsolateName() {
357-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
385+
std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
358386
return root_isolate ? root_isolate->debug_name() : "";
359387
}
360388

361389
bool RuntimeController::HasLivePorts() {
362-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
390+
std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
363391
if (!root_isolate) {
364392
return false;
365393
}
@@ -368,11 +396,20 @@ bool RuntimeController::HasLivePorts() {
368396
}
369397

370398
tonic::DartErrorHandleType RuntimeController::GetLastError() {
371-
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
399+
std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate().lock();
372400
return root_isolate ? root_isolate->GetLastError() : tonic::kNoError;
373401
}
374402

375403
std::weak_ptr<DartIsolate> RuntimeController::GetRootIsolate() {
404+
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
405+
if (root_isolate) {
406+
return root_isolate_;
407+
}
408+
409+
// Root isolate is not yet created, get it and do some configuration.
410+
FML_DCHECK(create_and_config_root_isolate_.valid());
411+
create_and_config_root_isolate_.get();
412+
376413
return root_isolate_;
377414
}
378415

runtime/runtime_controller.h

Lines changed: 4 additions & 1 deletion
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,13 @@ class RuntimeController final : public PlatformConfigurationClient {
467468
std::string advisory_script_entrypoint_;
468469
std::function<void(int64_t)> idle_notification_callback_;
469470
PlatformData platform_data_;
471+
std::future<void> create_and_config_root_isolate_;
470472
std::weak_ptr<DartIsolate> root_isolate_;
471473
std::pair<bool, uint32_t> root_isolate_return_code_ = {false, 0};
472474
const fml::closure isolate_create_callback_;
473475
const fml::closure isolate_shutdown_callback_;
474476
std::shared_ptr<const fml::Mapping> persistent_isolate_data_;
477+
fml::WeakPtrFactory<RuntimeController> weak_factory_;
475478

476479
PlatformConfiguration* GetPlatformConfigurationIfAvailable();
477480

runtime/runtime_delegate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class RuntimeDelegate {
3232

3333
virtual FontCollection& GetFontCollection() = 0;
3434

35+
virtual void OnRootIsolateCreated() = 0;
36+
3537
virtual void UpdateIsolateDescription(const std::string isolate_name,
3638
int64_t isolate_port) = 0;
3739

shell/common/engine.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,10 @@ void Engine::HandlePlatformMessage(fml::RefPtr<PlatformMessage> message) {
481481
}
482482
}
483483

484+
void Engine::OnRootIsolateCreated() {
485+
delegate_.OnRootIsolateCreated();
486+
}
487+
484488
void Engine::UpdateIsolateDescription(const std::string isolate_name,
485489
int64_t isolate_port) {
486490
delegate_.UpdateIsolateDescription(isolate_name, isolate_port);

shell/common/engine.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,15 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
185185
///
186186
virtual void OnPreEngineRestart() = 0;
187187

188+
//--------------------------------------------------------------------------
189+
/// @brief Notifies the shell that the root isolate is created.
190+
/// Currently, this information is to add to the service
191+
/// protocol list of available root isolates running in the VM
192+
/// and their names so that the appropriate isolate can be
193+
/// selected in the tools for debugging and instrumentation.
194+
///
195+
virtual void OnRootIsolateCreated() = 0;
196+
188197
//--------------------------------------------------------------------------
189198
/// @brief Notifies the shell of the name of the root isolate and its
190199
/// port when that isolate is launched, restarted (in the
@@ -792,6 +801,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
792801
// |RuntimeDelegate|
793802
void HandlePlatformMessage(fml::RefPtr<PlatformMessage> message) override;
794803

804+
void OnRootIsolateCreated() override;
795805
// |RuntimeDelegate|
796806
void UpdateIsolateDescription(const std::string isolate_name,
797807
int64_t isolate_port) override;

shell/common/shell.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,6 @@ bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,
558558

559559
is_setup_ = true;
560560

561-
vm_->GetServiceProtocol()->AddHandler(this, GetServiceProtocolDescription());
562-
563561
PersistentCache::GetCacheForProcess()->AddWorkerTaskRunner(
564562
task_runners_.GetIOTaskRunner());
565563

@@ -1097,6 +1095,18 @@ void Shell::OnPreEngineRestart() {
10971095
latch.Wait();
10981096
}
10991097

1098+
// |Engine::Delegate|
1099+
void Shell::OnRootIsolateCreated() {
1100+
fml::TaskRunner::RunNowOrPostTask(
1101+
task_runners_.GetPlatformTaskRunner(),
1102+
[self = weak_factory_.GetWeakPtr()]() {
1103+
if (self) {
1104+
self->vm_->GetServiceProtocol()->AddHandler(
1105+
self.get(), self->GetServiceProtocolDescription());
1106+
}
1107+
});
1108+
}
1109+
11001110
// |Engine::Delegate|
11011111
void Shell::UpdateIsolateDescription(const std::string isolate_name,
11021112
int64_t isolate_port) {

shell/common/shell.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,9 @@ class Shell final : public PlatformView::Delegate,
513513
// |Engine::Delegate|
514514
void OnPreEngineRestart() override;
515515

516+
// |Engine::Delegate|
517+
void OnRootIsolateCreated() override;
518+
516519
// |Engine::Delegate|
517520
void UpdateIsolateDescription(const std::string isolate_name,
518521
int64_t isolate_port) override;

0 commit comments

Comments
 (0)