@@ -18,7 +18,10 @@ namespace flutter {
18
18
19
19
RuntimeController::RuntimeController (RuntimeDelegate& client,
20
20
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 ) {}
22
25
23
26
RuntimeController::RuntimeController (
24
27
RuntimeDelegate& p_client,
@@ -50,48 +53,80 @@ RuntimeController::RuntimeController(
50
53
platform_data_(std::move(p_platform_data)),
51
54
isolate_create_callback_(p_isolate_create_callback),
52
55
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.
55
61
// It will be run at a later point when the engine provides a run
56
62
// 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
+ });
95
130
}
96
131
97
132
RuntimeController::~RuntimeController () {
@@ -107,8 +142,8 @@ RuntimeController::~RuntimeController() {
107
142
}
108
143
}
109
144
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 ();
112
147
if (root_isolate) {
113
148
return root_isolate->GetPhase () == DartIsolate::Phase::Running;
114
149
}
@@ -234,7 +269,7 @@ bool RuntimeController::ReportTimings(std::vector<int64_t> timings) {
234
269
}
235
270
236
271
bool RuntimeController::NotifyIdle (int64_t deadline) {
237
- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
272
+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
238
273
if (!root_isolate) {
239
274
return false ;
240
275
}
@@ -291,7 +326,7 @@ bool RuntimeController::DispatchSemanticsAction(int32_t id,
291
326
292
327
PlatformConfiguration*
293
328
RuntimeController::GetPlatformConfigurationIfAvailable () {
294
- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
329
+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
295
330
return root_isolate ? root_isolate->platform_configuration () : nullptr ;
296
331
}
297
332
@@ -353,17 +388,17 @@ RuntimeController::ComputePlatformResolvedLocale(
353
388
}
354
389
355
390
Dart_Port RuntimeController::GetMainPort () {
356
- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
391
+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
357
392
return root_isolate ? root_isolate->main_port () : ILLEGAL_PORT;
358
393
}
359
394
360
395
std::string RuntimeController::GetIsolateName () {
361
- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
396
+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
362
397
return root_isolate ? root_isolate->debug_name () : " " ;
363
398
}
364
399
365
400
bool RuntimeController::HasLivePorts () {
366
- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
401
+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
367
402
if (!root_isolate) {
368
403
return false ;
369
404
}
@@ -372,11 +407,20 @@ bool RuntimeController::HasLivePorts() {
372
407
}
373
408
374
409
tonic::DartErrorHandleType RuntimeController::GetLastError () {
375
- std::shared_ptr<DartIsolate> root_isolate = root_isolate_ .lock ();
410
+ std::shared_ptr<DartIsolate> root_isolate = GetRootIsolate () .lock ();
376
411
return root_isolate ? root_isolate->GetLastError () : tonic::kNoError ;
377
412
}
378
413
379
414
std::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
+
380
424
return root_isolate_;
381
425
}
382
426
0 commit comments