@@ -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,
@@ -52,49 +55,81 @@ RuntimeController::RuntimeController(
5255 platform_data_(std::move(p_platform_data)),
5356 isolate_create_callback_(p_isolate_create_callback),
5457 isolate_shutdown_callback_(p_isolate_shutdown_callback),
55- persistent_isolate_data_(std::move(p_persistent_isolate_data)) {
56- // Create the root isolate as soon as the runtime controller is initialized.
58+ persistent_isolate_data_(std::move(p_persistent_isolate_data)),
59+ weak_factory_(this ) {
60+ // Create the root isolate as soon as the runtime controller is initialized,
61+ // but not using a synchronous way to avoid blocking the platform thread a
62+ // long time as it is waiting while creating `Shell` on that platform thread.
5763 // It will be run at a later point when the engine provides a run
5864 // configuration and then runs the isolate.
59- auto strong_root_isolate =
60- DartIsolate::CreateRootIsolate (
61- vm_->GetVMData ()->GetSettings (), //
62- isolate_snapshot_, //
63- task_runners_, //
64- std::make_unique<PlatformConfiguration>(this ), //
65- snapshot_delegate_, //
66- hint_freed_delegate_, //
67- io_manager_, //
68- unref_queue_, //
69- image_decoder_, //
70- p_advisory_script_uri, //
71- p_advisory_script_entrypoint, //
72- nullptr , //
73- isolate_create_callback_, //
74- isolate_shutdown_callback_ //
75- )
76- .lock ();
77-
78- FML_CHECK (strong_root_isolate) << " Could not create root isolate." ;
79-
80- // The root isolate ivar is weak.
81- root_isolate_ = strong_root_isolate;
82-
83- strong_root_isolate->SetReturnCodeCallback ([this ](uint32_t code) {
84- root_isolate_return_code_ = {true , code};
85- });
86-
87- if (auto * platform_configuration = GetPlatformConfigurationIfAvailable ()) {
88- tonic::DartState::Scope scope (strong_root_isolate);
89- platform_configuration->DidCreateIsolate ();
90- if (!FlushRuntimeStateToIsolate ()) {
91- FML_DLOG (ERROR) << " Could not setup initial isolate state." ;
92- }
93- } else {
94- FML_DCHECK (false ) << " RuntimeController created without window binding." ;
95- }
96-
97- FML_DCHECK (Dart_CurrentIsolate () == nullptr );
65+ create_and_config_root_isolate_ =
66+ std::async (std::launch::deferred, [self = weak_factory_.GetWeakPtr ()]() {
67+ if (!self) {
68+ return ;
69+ }
70+
71+ auto strong_root_isolate =
72+ DartIsolate::CreateRootIsolate (
73+ self->vm_ ->GetVMData ()->GetSettings (), //
74+ self->isolate_snapshot_ , //
75+ self->task_runners_ , //
76+ std::make_unique<PlatformConfiguration>(self.get ()), //
77+ self->snapshot_delegate_ , //
78+ self->hint_freed_delegate_ , //
79+ self->io_manager_ , //
80+ self->unref_queue_ , //
81+ self->image_decoder_ , //
82+ self->advisory_script_uri_ , //
83+ self->advisory_script_entrypoint_ , //
84+ nullptr , //
85+ self->isolate_create_callback_ , //
86+ self->isolate_shutdown_callback_ //
87+ )
88+ .lock ();
89+
90+ FML_CHECK (strong_root_isolate) << " Could not create root isolate." ;
91+
92+ // The root isolate ivar is weak.
93+ self->root_isolate_ = strong_root_isolate;
94+
95+ strong_root_isolate->SetReturnCodeCallback ([self](uint32_t code) {
96+ if (!self) {
97+ return ;
98+ }
99+
100+ self->root_isolate_return_code_ = {true , code};
101+ });
102+
103+ if (auto * platform_configuration =
104+ self->GetPlatformConfigurationIfAvailable ()) {
105+ tonic::DartState::Scope scope (strong_root_isolate);
106+ platform_configuration->DidCreateIsolate ();
107+ if (!self->FlushRuntimeStateToIsolate ()) {
108+ FML_DLOG (ERROR) << " Could not setup initial isolate state." ;
109+ }
110+ } else {
111+ FML_DCHECK (false )
112+ << " RuntimeController created without window binding." ;
113+ }
114+
115+ FML_DCHECK (Dart_CurrentIsolate () == nullptr );
116+
117+ self->client_ .OnRootIsolateCreated ();
118+ return ;
119+ });
120+
121+ // We're still trying to create the root isolate as soon as possible here on
122+ // the UI thread although it's deferred a little bit by
123+ // std::async(std::launch::deferred, ...). So the callers of `GetRootIsolate`
124+ // should get a quick return after this UI thread task.
125+ task_runners_.GetUITaskRunner ()->PostTask (
126+ [self = weak_factory_.GetWeakPtr ()]() {
127+ if (!self) {
128+ return ;
129+ }
130+
131+ self->GetRootIsolate ();
132+ });
98133}
99134
100135RuntimeController::~RuntimeController () {
@@ -110,8 +145,8 @@ RuntimeController::~RuntimeController() {
110145 }
111146}
112147
113- bool RuntimeController::IsRootIsolateRunning () const {
114- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
148+ bool RuntimeController::IsRootIsolateRunning () {
149+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
115150 if (root_isolate) {
116151 return root_isolate->GetPhase () == DartIsolate::Phase::Running;
117152 }
@@ -238,7 +273,7 @@ bool RuntimeController::ReportTimings(std::vector<int64_t> timings) {
238273}
239274
240275bool RuntimeController::NotifyIdle (int64_t deadline, size_t freed_hint) {
241- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
276+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
242277 if (!root_isolate) {
243278 return false ;
244279 }
@@ -298,7 +333,7 @@ bool RuntimeController::DispatchSemanticsAction(int32_t id,
298333
299334PlatformConfiguration*
300335RuntimeController::GetPlatformConfigurationIfAvailable () {
301- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
336+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
302337 return root_isolate ? root_isolate->platform_configuration () : nullptr ;
303338}
304339
@@ -360,17 +395,17 @@ RuntimeController::ComputePlatformResolvedLocale(
360395}
361396
362397Dart_Port RuntimeController::GetMainPort () {
363- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
398+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
364399 return root_isolate ? root_isolate->main_port () : ILLEGAL_PORT;
365400}
366401
367402std::string RuntimeController::GetIsolateName () {
368- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
403+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
369404 return root_isolate ? root_isolate->debug_name () : " " ;
370405}
371406
372407bool RuntimeController::HasLivePorts () {
373- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
408+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
374409 if (!root_isolate) {
375410 return false ;
376411 }
@@ -379,11 +414,20 @@ bool RuntimeController::HasLivePorts() {
379414}
380415
381416tonic::DartErrorHandleType RuntimeController::GetLastError () {
382- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
417+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
383418 return root_isolate ? root_isolate->GetLastError () : tonic::kNoError ;
384419}
385420
386421std::weak_ptr<DartIsolate> RuntimeController::GetRootIsolate () {
422+ std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock ();
423+ if (root_isolate) {
424+ return root_isolate_;
425+ }
426+
427+ // Root isolate is not yet created, get it and do some configuration.
428+ FML_DCHECK (create_and_config_root_isolate_.valid ());
429+ create_and_config_root_isolate_.get ();
430+
387431 return root_isolate_;
388432}
389433
0 commit comments