@@ -99,22 +99,27 @@ class AutoIsolateShutdown {
9999 AutoIsolateShutdown () = default ;
100100
101101 AutoIsolateShutdown (std::shared_ptr<DartIsolate> isolate,
102- fml::RefPtr<fml::TaskRunner> runner)
103- : isolate_(std::move(isolate)), runner_(std::move(runner)) {}
102+ fml::RefPtr<fml::TaskRunner> runner,
103+ bool confirm_shutdown)
104+ : isolate_(std::move(isolate)),
105+ runner_ (std::move(runner)),
106+ confirm_shutdown_(confirm_shutdown) {}
104107
105108 ~AutoIsolateShutdown () {
106109 if (!IsValid ()) {
107110 return ;
108111 }
109112 fml::AutoResetWaitableEvent latch;
110- fml::TaskRunner::RunNowOrPostTask (runner_, [isolate = isolate_, &latch]() {
111- FML_LOG (INFO) << " Shutting down isolate." ;
112- if (!isolate->Shutdown ()) {
113- FML_LOG (ERROR) << " Could not shutdown isolate." ;
114- FML_CHECK (false );
115- }
116- latch.Signal ();
117- });
113+ fml::TaskRunner::RunNowOrPostTask (
114+ runner_,
115+ [isolate = isolate_, &latch, confirm_shutdown = confirm_shutdown_]() {
116+ FML_LOG (INFO) << " Shutting down isolate." ;
117+ if (!isolate->Shutdown () && confirm_shutdown) {
118+ FML_LOG (ERROR) << " Could not shutdown isolate." ;
119+ FML_CHECK (false );
120+ }
121+ latch.Signal ();
122+ });
118123 latch.Wait ();
119124 }
120125
@@ -149,6 +154,7 @@ class AutoIsolateShutdown {
149154 private:
150155 std::shared_ptr<DartIsolate> isolate_;
151156 fml::RefPtr<fml::TaskRunner> runner_;
157+ bool confirm_shutdown_;
152158
153159 FML_DISALLOW_COPY_AND_ASSIGN (AutoIsolateShutdown);
154160};
@@ -158,7 +164,8 @@ static void RunDartCodeInIsolate(DartVMRef& vm_ref,
158164 const Settings& settings,
159165 fml::RefPtr<fml::TaskRunner> task_runner,
160166 std::string entrypoint,
161- const std::vector<std::string>& args) {
167+ const std::vector<std::string>& args,
168+ bool confirm_shutdown) {
162169 FML_CHECK (task_runner->RunsTasksOnCurrentThread ());
163170
164171 if (!vm_ref) {
@@ -193,8 +200,8 @@ static void RunDartCodeInIsolate(DartVMRef& vm_ref,
193200 settings.isolate_shutdown_callback // isolate shutdown callback
194201 );
195202
196- auto root_isolate =
197- std::make_unique<AutoIsolateShutdown>( weak_isolate.lock (), task_runner);
203+ auto root_isolate = std::make_unique<AutoIsolateShutdown>(
204+ weak_isolate.lock (), task_runner, confirm_shutdown );
198205
199206 if (!root_isolate->IsValid ()) {
200207 FML_LOG (ERROR) << " Could not create isolate." ;
@@ -267,13 +274,14 @@ static std::unique_ptr<AutoIsolateShutdown> RunDartCodeInIsolate(
267274 const Settings& settings,
268275 fml::RefPtr<fml::TaskRunner> task_runner,
269276 std::string entrypoint,
270- const std::vector<std::string>& args) {
277+ const std::vector<std::string>& args,
278+ bool confirm_shutdown) {
271279 std::unique_ptr<AutoIsolateShutdown> result;
272280 fml::AutoResetWaitableEvent latch;
273281 fml::TaskRunner::RunNowOrPostTask (
274282 task_runner, fml::MakeCopyable ([&]() mutable {
275283 RunDartCodeInIsolate (vm_ref, result, settings, task_runner, entrypoint,
276- args);
284+ args, confirm_shutdown );
277285 latch.Signal ();
278286 }));
279287 latch.Wait ();
@@ -285,7 +293,7 @@ TEST_F(DartIsolateTest, IsolateCanLoadAndRunDartCode) {
285293 const auto settings = CreateSettingsForFixture ();
286294 auto vm_ref = DartVMRef::Create (settings);
287295 auto isolate = RunDartCodeInIsolate (vm_ref, settings, GetCurrentTaskRunner (),
288- " main" , {});
296+ " main" , {}, true );
289297 ASSERT_TRUE (isolate);
290298 ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
291299}
@@ -295,7 +303,7 @@ TEST_F(DartIsolateTest, IsolateCannotLoadAndRunUnknownDartEntrypoint) {
295303 const auto settings = CreateSettingsForFixture ();
296304 auto vm_ref = DartVMRef::Create (settings);
297305 auto isolate = RunDartCodeInIsolate (vm_ref, settings, GetCurrentTaskRunner (),
298- " thisShouldNotExist" , {});
306+ " thisShouldNotExist" , {}, true );
299307 ASSERT_FALSE (isolate);
300308}
301309
@@ -304,7 +312,7 @@ TEST_F(DartIsolateTest, CanRunDartCodeCodeSynchronously) {
304312 const auto settings = CreateSettingsForFixture ();
305313 auto vm_ref = DartVMRef::Create (settings);
306314 auto isolate = RunDartCodeInIsolate (vm_ref, settings, GetCurrentTaskRunner (),
307- " main" , {});
315+ " main" , {}, true );
308316
309317 ASSERT_TRUE (isolate);
310318 ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
@@ -328,7 +336,7 @@ TEST_F(DartIsolateTest, CanRegisterNativeCallback) {
328336 const auto settings = CreateSettingsForFixture ();
329337 auto vm_ref = DartVMRef::Create (settings);
330338 auto isolate = RunDartCodeInIsolate (vm_ref, settings, CreateNewThread (),
331- " canRegisterNativeCallback" , {});
339+ " canRegisterNativeCallback" , {}, true );
332340 ASSERT_TRUE (isolate);
333341 ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
334342 latch.Wait ();
@@ -351,7 +359,7 @@ TEST_F(DartIsolateTest, CanSaveCompilationTrace) {
351359 const auto settings = CreateSettingsForFixture ();
352360 auto vm_ref = DartVMRef::Create (settings);
353361 auto isolate = RunDartCodeInIsolate (vm_ref, settings, CreateNewThread (),
354- " testCanSaveCompilationTrace" , {});
362+ " testCanSaveCompilationTrace" , {}, true );
355363 ASSERT_TRUE (isolate);
356364 ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
357365
@@ -377,8 +385,9 @@ TEST_F(DartIsolateTest, CanLaunchSecondaryIsolates) {
377385 child_shutdown_latch.Signal ();
378386 };
379387 auto vm_ref = DartVMRef::Create (settings);
380- auto isolate = RunDartCodeInIsolate (vm_ref, settings, CreateNewThread (),
381- " testCanLaunchSecondaryIsolate" , {});
388+ auto isolate =
389+ RunDartCodeInIsolate (vm_ref, settings, CreateNewThread (),
390+ " testCanLaunchSecondaryIsolate" , {}, true );
382391 ASSERT_TRUE (isolate);
383392 ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
384393 child_shutdown_latch.Wait (); // wait for child isolate to shutdown first
@@ -397,13 +406,54 @@ TEST_F(DartIsolateTest, CanRecieveArguments) {
397406
398407 const auto settings = CreateSettingsForFixture ();
399408 auto vm_ref = DartVMRef::Create (settings);
400- auto isolate = RunDartCodeInIsolate (vm_ref, settings, CreateNewThread (),
401- " testCanRecieveArguments" , {" arg1" });
409+ auto isolate =
410+ RunDartCodeInIsolate (vm_ref, settings, CreateNewThread (),
411+ " testCanRecieveArguments" , {" arg1" }, true );
402412 ASSERT_TRUE (isolate);
403413 ASSERT_EQ (isolate->get ()->GetPhase (), DartIsolate::Phase::Running);
404414
405415 latch.Wait ();
406416}
407417
418+ TEST_F (DartIsolateTest, RootIsolateShutdownStopsChildIsolates) {
419+ ASSERT_FALSE (DartVMRef::IsInstanceRunning ());
420+ fml::CountDownLatch latch (12 );
421+ fml::CountDownLatch shutdown_latch (5 );
422+ AddNativeCallback (" NotifyNative" ,
423+ CREATE_NATIVE_ENTRY (([&latch](Dart_NativeArguments args) {
424+ latch.CountDown ();
425+ })));
426+ AddNativeCallback (
427+ " PassMessage" , CREATE_NATIVE_ENTRY (([&latch](Dart_NativeArguments args) {
428+ auto message = tonic::DartConverter<std::string>::FromDart (
429+ Dart_GetNativeArgument (args, 0 ));
430+ ASSERT_EQ (" In child Isolate." , message);
431+ latch.CountDown ();
432+ })));
433+
434+ size_t destruction_callback_count = 0 ;
435+ auto settings = CreateSettingsForFixture ();
436+ settings.isolate_shutdown_callback = [&shutdown_latch,
437+ &destruction_callback_count]() {
438+ destruction_callback_count++;
439+ shutdown_latch.CountDown ();
440+ };
441+ auto vm_ref = DartVMRef::Create (settings);
442+ auto vm_data = vm_ref.GetVMData ();
443+
444+ std::unique_ptr<AutoIsolateShutdown> isolate;
445+ fml::RefPtr<fml::TaskRunner> task_runner = CreateNewThread ();
446+ fml::TaskRunner::RunNowOrPostTask (
447+ task_runner, fml::MakeCopyable ([&]() mutable {
448+ RunDartCodeInIsolate (vm_ref, isolate, settings, task_runner,
449+ " testSecondaryIsolateShutdown" , {}, false );
450+ }));
451+ latch.Wait (); // wait for last NotifyNative called by main isolate
452+ ASSERT_TRUE (isolate->get ()->Shutdown () || true );
453+ shutdown_latch.Wait ();
454+ // root isolate will be auto-shutdown
455+ ASSERT_EQ (destruction_callback_count, 5u );
456+ }
457+
408458} // namespace testing
409459} // namespace flutter
0 commit comments