diff --git a/runtime/dart_isolate_unittests.cc b/runtime/dart_isolate_unittests.cc index cc9272edc00b1..5a752ecc3a6a2 100644 --- a/runtime/dart_isolate_unittests.cc +++ b/runtime/dart_isolate_unittests.cc @@ -335,7 +335,54 @@ TEST_F(DartSecondaryIsolateTest, CanLaunchSecondaryIsolates) { // root isolate will be auto-shutdown } -TEST_F(DartIsolateTest, CanReceiveArguments) { +static thread_local bool is_engine_worker = false; + +TEST_F(DartSecondaryIsolateTest, VMTasksRunOnEngineThreads) { + AddNativeCallback("NotifyNative", + CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) { + LatchCountDown(); + }))); + AddNativeCallback("PassMessage", + CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) { + // Child isolate is running on concurrent message loop + // worker. + ASSERT_TRUE(is_engine_worker); + LatchCountDown(); + }))); + auto settings = CreateSettingsForFixture(); + settings.root_isolate_shutdown_callback = [this]() { + RootIsolateShutdownSignal(); + }; + settings.isolate_shutdown_callback = [this]() { ChildShutdownSignal(); }; + auto vm_ref = DartVMRef::Create(settings); + + auto loop = vm_ref->GetConcurrentMessageLoop(); + fml::CountDownLatch latch(loop->GetWorkerCount()); + vm_ref->GetConcurrentMessageLoop()->PostTaskToAllWorkers([&] { + is_engine_worker = true; + latch.CountDown(); + }); + latch.Wait(); + + auto thread = CreateNewThread(); + TaskRunners task_runners(GetCurrentTestName(), // + thread, // + thread, // + thread, // + thread // + ); + auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners, + "testCanLaunchSecondaryIsolate", {}, + GetDefaultKernelFilePath()); + ASSERT_TRUE(isolate); + ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running); + ChildShutdownWait(); // wait for child isolate to shutdown first + ASSERT_FALSE(RootIsolateIsSignaled()); + LatchWait(); // wait for last NotifyNative called by main isolate + // root isolate will be auto-shutdown +} + +TEST_F(DartIsolateTest, CanRecieveArguments) { AddNativeCallback("NotifyNative", CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) { ASSERT_TRUE(tonic::DartConverter::FromDart( diff --git a/runtime/dart_vm.cc b/runtime/dart_vm.cc index 17591c9d05d5f..f396be147b257 100644 --- a/runtime/dart_vm.cc +++ b/runtime/dart_vm.cc @@ -170,6 +170,14 @@ Dart_Handle GetVMServiceAssetsArchiveCallback() { #endif } +void PostTaskCallback(void* post_task_data, + Dart_Task task, + Dart_TaskData task_data) { + auto* dart_vm = reinterpret_cast(post_task_data); + dart_vm->GetConcurrentWorkerTaskRunner()->PostTask( + [task] { Dart_RunTask(task); }); +} + static const char kStdoutStreamId[] = "Stdout"; static const char kStderrStreamId[] = "Stderr"; @@ -442,6 +450,8 @@ DartVM::DartVM(std::shared_ptr vm_data, params.thread_exit = ThreadExitCallback; params.get_service_assets = GetVMServiceAssetsArchiveCallback; params.entropy_source = dart::bin::GetEntropy; + params.post_task = PostTaskCallback; + params.post_task_data = this; DartVMInitializer::Initialize(¶ms); // Send the earliest available timestamp in the application lifecycle to // timeline. The difference between this timestamp and the time we render @@ -476,6 +486,10 @@ DartVM::DartVM(std::shared_ptr vm_data, Dart_SetDartLibrarySourcesKernel(dart_library_sources->GetMapping(), dart_library_sources->GetSize()); } + + // Update thread names now that the Dart VM is initialized. + concurrent_message_loop_->PostTaskToAllWorkers( + [] { Dart_SetThreadName("FlutterConcurrentMessageLoopWorker"); }); } DartVM::~DartVM() {