@@ -18,7 +18,10 @@ namespace flutter {
1818
1919RuntimeController::RuntimeController (RuntimeDelegate& client,
2020 TaskRunners p_task_runners)
21- : client_(client), vm_(nullptr ), task_runners_(p_task_runners) {}
21+ : client_(client),
22+ vm_ (nullptr ),
23+ task_runners_(p_task_runners),
24+ weak_factory_(this ) {}
2225
2326RuntimeController::RuntimeController (
2427 RuntimeDelegate& p_client,
@@ -50,48 +53,80 @@ RuntimeController::RuntimeController(
5053 platform_data_(std::move(p_platform_data)),
5154 isolate_create_callback_(p_isolate_create_callback),
5255 isolate_shutdown_callback_(p_isolate_shutdown_callback),
53- persistent_isolate_data_(std::move(p_persistent_isolate_data)) {
54- // Create the root isolate as soon as the runtime controller is initialized.
56+ persistent_isolate_data_(std::move(p_persistent_isolate_data)),
57+ weak_factory_(this ) {
58+ // Create the root isolate as soon as the runtime controller is initialized,
59+ // but not using a synchronous way to avoid blocking the platform thread a
60+ // long time as it is waiting while creating `Shell` on that platform thread.
5561 // It will be run at a later point when the engine provides a run
5662 // configuration and then runs the isolate.
57- auto strong_root_isolate =
58- DartIsolate::CreateRootIsolate (
59- vm_->GetVMData ()->GetSettings (), //
60- isolate_snapshot_, //
61- task_runners_, //
62- std::make_unique<PlatformConfiguration>(this ), //
63- snapshot_delegate_, //
64- io_manager_, //
65- unref_queue_, //
66- image_decoder_, //
67- p_advisory_script_uri, //
68- p_advisory_script_entrypoint, //
69- nullptr , //
70- isolate_create_callback_, //
71- isolate_shutdown_callback_ //
72- )
73- .lock ();
74-
75- FML_CHECK (strong_root_isolate) << " Could not create root isolate." ;
76-
77- // The root isolate ivar is weak.
78- root_isolate_ = strong_root_isolate;
79-
80- strong_root_isolate->SetReturnCodeCallback ([this ](uint32_t code) {
81- root_isolate_return_code_ = {true , code};
82- });
83-
84- if (auto * platform_configuration = GetPlatformConfigurationIfAvailable ()) {
85- tonic::DartState::Scope scope (strong_root_isolate);
86- platform_configuration->DidCreateIsolate ();
87- if (!FlushRuntimeStateToIsolate ()) {
88- FML_DLOG (ERROR) << " Could not setup initial isolate state." ;
89- }
90- } else {
91- FML_DCHECK (false ) << " RuntimeController created without window binding." ;
92- }
93-
94- FML_DCHECK (Dart_CurrentIsolate () == nullptr );
63+ create_and_config_root_isolate_ =
64+ std::async (std::launch::deferred, [self = weak_factory_.GetWeakPtr ()]() {
65+ if (!self) {
66+ return ;
67+ }
68+
69+ auto strong_root_isolate =
70+ DartIsolate::CreateRootIsolate (
71+ self->vm_ ->GetVMData ()->GetSettings (), //
72+ self->isolate_snapshot_ , //
73+ self->task_runners_ , //
74+ std::make_unique<PlatformConfiguration>(self.get ()), //
75+ self->snapshot_delegate_ , //
76+ self->io_manager_ , //
77+ self->unref_queue_ , //
78+ self->image_decoder_ , //
79+ self->advisory_script_uri_ , //
80+ self->advisory_script_entrypoint_ , //
81+ nullptr , //
82+ self->isolate_create_callback_ , //
83+ self->isolate_shutdown_callback_ //
84+ )
85+ .lock ();
86+
87+ FML_CHECK (strong_root_isolate) << " Could not create root isolate." ;
88+
89+ // The root isolate ivar is weak.
90+ self->root_isolate_ = strong_root_isolate;
91+
92+ strong_root_isolate->SetReturnCodeCallback ([self](uint32_t code) {
93+ if (!self) {
94+ return ;
95+ }
96+
97+ self->root_isolate_return_code_ = {true , code};
98+ });
99+
100+ if (auto * platform_configuration =
101+ self->GetPlatformConfigurationIfAvailable ()) {
102+ tonic::DartState::Scope scope (strong_root_isolate);
103+ platform_configuration->DidCreateIsolate ();
104+ if (!self->FlushRuntimeStateToIsolate ()) {
105+ FML_DLOG (ERROR) << " Could not setup initial isolate state." ;
106+ }
107+ } else {
108+ FML_DCHECK (false )
109+ << " RuntimeController created without window binding." ;
110+ }
111+
112+ FML_DCHECK (Dart_CurrentIsolate () == nullptr );
113+
114+ self->client_ .OnRootIsolateCreated ();
115+ return ;
116+ });
117+
118+ // We're still trying to create the root isolate as soon as possible here on
119+ // the UI thread although it's deferred a little bit by
120+ // std::async(std::launch::deferred, ...). So the callers of `GetRootIsolate`
121+ // should get a quick return after this UI thread task.
122+ task_runners_.GetUITaskRunner ()->PostTask (
123+ [self = weak_factory_.GetWeakPtr ()]() {
124+ if (!self) {
125+ return ;
126+ }
127+
128+ self->GetRootIsolate ();
129+ });
95130}
96131
97132RuntimeController::~RuntimeController () {
@@ -107,8 +142,8 @@ RuntimeController::~RuntimeController() {
107142 }
108143}
109144
110- bool RuntimeController::IsRootIsolateRunning () const {
111- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
145+ bool RuntimeController::IsRootIsolateRunning () {
146+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
112147 if (root_isolate) {
113148 return root_isolate->GetPhase () == DartIsolate::Phase::Running;
114149 }
@@ -234,7 +269,7 @@ bool RuntimeController::ReportTimings(std::vector<int64_t> timings) {
234269}
235270
236271bool RuntimeController::NotifyIdle (int64_t deadline) {
237- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
272+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
238273 if (!root_isolate) {
239274 return false ;
240275 }
@@ -291,7 +326,7 @@ bool RuntimeController::DispatchSemanticsAction(int32_t id,
291326
292327PlatformConfiguration*
293328RuntimeController::GetPlatformConfigurationIfAvailable () {
294- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
329+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
295330 return root_isolate ? root_isolate->platform_configuration () : nullptr ;
296331}
297332
@@ -353,17 +388,17 @@ RuntimeController::ComputePlatformResolvedLocale(
353388}
354389
355390Dart_Port RuntimeController::GetMainPort () {
356- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
391+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
357392 return root_isolate ? root_isolate->main_port () : ILLEGAL_PORT;
358393}
359394
360395std::string RuntimeController::GetIsolateName () {
361- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
396+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
362397 return root_isolate ? root_isolate->debug_name () : " " ;
363398}
364399
365400bool RuntimeController::HasLivePorts () {
366- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
401+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
367402 if (!root_isolate) {
368403 return false ;
369404 }
@@ -372,11 +407,20 @@ bool RuntimeController::HasLivePorts() {
372407}
373408
374409tonic::DartErrorHandleType RuntimeController::GetLastError () {
375- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
410+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
376411 return root_isolate ? root_isolate->GetLastError () : tonic::kNoError ;
377412}
378413
379414std::weak_ptr<DartIsolate> RuntimeController::GetRootIsolate () {
415+ std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock ();
416+ if (root_isolate) {
417+ return root_isolate_;
418+ }
419+
420+ // Root isolate is not yet created, get it and do some configuration.
421+ FML_DCHECK (create_and_config_root_isolate_.valid ());
422+ create_and_config_root_isolate_.get ();
423+
380424 return root_isolate_;
381425}
382426
0 commit comments