From 3b80f04517d195baa3a5af5cf44e9ecc322368c3 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 4 Mar 2020 12:00:19 -0800 Subject: [PATCH 1/2] fix OOL def --- testing/BUILD.gn | 1 + testing/dart_isolate_runner.cc | 176 +++++++++++++++++++++++++++++++++ testing/dart_isolate_runner.h | 175 +++++--------------------------- 3 files changed, 199 insertions(+), 153 deletions(-) create mode 100644 testing/dart_isolate_runner.cc diff --git a/testing/BUILD.gn b/testing/BUILD.gn index ba6bdf7237898..67a920f10128b 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn @@ -43,6 +43,7 @@ source_set("dart") { testonly = true sources = [ + "dart_isolate_runner.cc", "dart_isolate_runner.h", "elf_loader.cc", "elf_loader.h", diff --git a/testing/dart_isolate_runner.cc b/testing/dart_isolate_runner.cc new file mode 100644 index 0000000000000..fd1eb24508c65 --- /dev/null +++ b/testing/dart_isolate_runner.cc @@ -0,0 +1,176 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/testing/dart_isolate_runner.h" + +namespace flutter { +namespace testing { +AutoIsolateShutdown::AutoIsolateShutdown(std::shared_ptr isolate, + fml::RefPtr runner) + : isolate_(std::move(isolate)), runner_(std::move(runner)) {} + +AutoIsolateShutdown::~AutoIsolateShutdown() { + if (!IsValid()) { + return; + } + fml::AutoResetWaitableEvent latch; + fml::TaskRunner::RunNowOrPostTask( + runner_, [isolate = std::move(isolate_), &latch]() { + if (!isolate->Shutdown()) { + FML_LOG(ERROR) << "Could not shutdown isolate."; + FML_CHECK(false); + } + latch.Signal(); + }); + latch.Wait(); +} + +FML_WARN_UNUSED_RESULT +bool AutoIsolateShutdown::RunInIsolateScope(std::function closure) { + if (!IsValid()) { + return false; + } + + bool result = false; + fml::AutoResetWaitableEvent latch; + fml::TaskRunner::RunNowOrPostTask( + runner_, [this, &result, &latch, closure]() { + tonic::DartIsolateScope scope(isolate_->isolate()); + tonic::DartApiScope api_scope; + if (closure) { + result = closure(); + } + latch.Signal(); + }); + latch.Wait(); + return true; +} + +void RunDartCodeInIsolate(DartVMRef& vm_ref, + std::unique_ptr& result, + const Settings& settings, + const TaskRunners& task_runners, + std::string entrypoint, + const std::vector& args, + const std::string& fixtures_path, + fml::WeakPtr io_manager) { + FML_CHECK(task_runners.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); + + if (!vm_ref) { + return; + } + + auto vm_data = vm_ref.GetVMData(); + + if (!vm_data) { + return; + } + + auto weak_isolate = DartIsolate::CreateRootIsolate( + vm_data->GetSettings(), // settings + vm_data->GetIsolateSnapshot(), // isolate snapshot + std::move(task_runners), // task runners + nullptr, // window + {}, // snapshot delegate + io_manager, // io manager + {}, // unref queue + {}, // image decoder + "main.dart", // advisory uri + "main", // advisory entrypoint + nullptr, // flags + settings.isolate_create_callback, // isolate create callback + settings.isolate_shutdown_callback // isolate shutdown callback + ); + + auto root_isolate = std::make_unique( + weak_isolate.lock(), task_runners.GetUITaskRunner()); + + if (!root_isolate->IsValid()) { + FML_LOG(ERROR) << "Could not create isolate."; + return; + } + + if (root_isolate->get()->GetPhase() != DartIsolate::Phase::LibrariesSetup) { + FML_LOG(ERROR) << "Created isolate is in unexpected phase."; + return; + } + + if (!DartVM::IsRunningPrecompiledCode()) { + auto kernel_file_path = + fml::paths::JoinPaths({fixtures_path, "kernel_blob.bin"}); + + if (!fml::IsFile(kernel_file_path)) { + FML_LOG(ERROR) << "Could not locate kernel file."; + return; + } + + auto kernel_file = fml::OpenFile(kernel_file_path.c_str(), false, + fml::FilePermission::kRead); + + if (!kernel_file.is_valid()) { + FML_LOG(ERROR) << "Kernel file descriptor was invalid."; + return; + } + + auto kernel_mapping = std::make_unique(kernel_file); + + if (kernel_mapping->GetMapping() == nullptr) { + FML_LOG(ERROR) << "Could not setup kernel mapping."; + return; + } + + if (!root_isolate->get()->PrepareForRunningFromKernel( + std::move(kernel_mapping))) { + FML_LOG(ERROR) + << "Could not prepare to run the isolate from the kernel file."; + return; + } + } else { + if (!root_isolate->get()->PrepareForRunningFromPrecompiledCode()) { + FML_LOG(ERROR) + << "Could not prepare to run the isolate from precompiled code."; + return; + } + } + + if (root_isolate->get()->GetPhase() != DartIsolate::Phase::Ready) { + FML_LOG(ERROR) << "Isolate is in unexpected phase."; + return; + } + + if (!root_isolate->get()->Run(entrypoint, args, + settings.root_isolate_create_callback)) { + FML_LOG(ERROR) << "Could not run the method \"" << entrypoint + << "\" in the isolate."; + return; + } + + root_isolate->get()->AddIsolateShutdownCallback( + settings.root_isolate_shutdown_callback); + + result = std::move(root_isolate); +} + +std::unique_ptr RunDartCodeInIsolate( + DartVMRef& vm_ref, + const Settings& settings, + const TaskRunners& task_runners, + std::string entrypoint, + const std::vector& args, + const std::string& fixtures_path, + fml::WeakPtr io_manager) { + std::unique_ptr result; + fml::AutoResetWaitableEvent latch; + fml::TaskRunner::RunNowOrPostTask( + task_runners.GetPlatformTaskRunner(), fml::MakeCopyable([&]() mutable { + RunDartCodeInIsolate(vm_ref, result, settings, task_runners, entrypoint, + args, fixtures_path, io_manager); + latch.Signal(); + })); + latch.Wait(); + return result; +} + +} // namespace testing +} // namespace flutter diff --git a/testing/dart_isolate_runner.h b/testing/dart_isolate_runner.h index aca09435ea226..f7a3db1fb6a59 100644 --- a/testing/dart_isolate_runner.h +++ b/testing/dart_isolate_runner.h @@ -2,10 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef FLUTTER_TESTING_DART_ISOLATE_RUNNER_H_ +#define FLUTTER_TESTING_DART_ISOLATE_RUNNER_H_ + +#include "flutter/common/task_runners.h" #include "flutter/fml/make_copyable.h" #include "flutter/fml/paths.h" #include "flutter/fml/synchronization/waitable_event.h" #include "flutter/fml/thread.h" +#include "flutter/runtime/dart_isolate.h" +#include "flutter/runtime/dart_vm.h" +#include "flutter/runtime/dart_vm_lifecycle.h" namespace flutter { namespace testing { @@ -15,47 +22,14 @@ class AutoIsolateShutdown { AutoIsolateShutdown() = default; AutoIsolateShutdown(std::shared_ptr isolate, - fml::RefPtr runner) - : isolate_(std::move(isolate)), runner_(std::move(runner)) {} + fml::RefPtr runner); - ~AutoIsolateShutdown() { - if (!IsValid()) { - return; - } - fml::AutoResetWaitableEvent latch; - fml::TaskRunner::RunNowOrPostTask( - runner_, [isolate = std::move(isolate_), &latch]() { - if (!isolate->Shutdown()) { - FML_LOG(ERROR) << "Could not shutdown isolate."; - FML_CHECK(false); - } - latch.Signal(); - }); - latch.Wait(); - } + ~AutoIsolateShutdown(); bool IsValid() const { return isolate_ != nullptr && runner_; } FML_WARN_UNUSED_RESULT - bool RunInIsolateScope(std::function closure) { - if (!IsValid()) { - return false; - } - - bool result = false; - fml::AutoResetWaitableEvent latch; - fml::TaskRunner::RunNowOrPostTask( - runner_, [this, &result, &latch, closure]() { - tonic::DartIsolateScope scope(isolate_->isolate()); - tonic::DartApiScope api_scope; - if (closure) { - result = closure(); - } - latch.Signal(); - }); - latch.Wait(); - return true; - } + bool RunInIsolateScope(std::function closure); DartIsolate* get() { FML_CHECK(isolate_); @@ -69,130 +43,25 @@ class AutoIsolateShutdown { FML_DISALLOW_COPY_AND_ASSIGN(AutoIsolateShutdown); }; -static void RunDartCodeInIsolate(DartVMRef& vm_ref, - std::unique_ptr& result, - const Settings& settings, - const TaskRunners& task_runners, - std::string entrypoint, - const std::vector& args, - const std::string& fixtures_path, - fml::WeakPtr io_manager = {}) { - FML_CHECK(task_runners.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); - - if (!vm_ref) { - return; - } - - auto vm_data = vm_ref.GetVMData(); - - if (!vm_data) { - return; - } - - auto weak_isolate = DartIsolate::CreateRootIsolate( - vm_data->GetSettings(), // settings - vm_data->GetIsolateSnapshot(), // isolate snapshot - std::move(task_runners), // task runners - nullptr, // window - {}, // snapshot delegate - io_manager, // io manager - {}, // unref queue - {}, // image decoder - "main.dart", // advisory uri - "main", // advisory entrypoint - nullptr, // flags - settings.isolate_create_callback, // isolate create callback - settings.isolate_shutdown_callback // isolate shutdown callback - ); - - auto root_isolate = std::make_unique( - weak_isolate.lock(), task_runners.GetUITaskRunner()); - - if (!root_isolate->IsValid()) { - FML_LOG(ERROR) << "Could not create isolate."; - return; - } - - if (root_isolate->get()->GetPhase() != DartIsolate::Phase::LibrariesSetup) { - FML_LOG(ERROR) << "Created isolate is in unexpected phase."; - return; - } - - if (!DartVM::IsRunningPrecompiledCode()) { - auto kernel_file_path = - fml::paths::JoinPaths({fixtures_path, "kernel_blob.bin"}); - - if (!fml::IsFile(kernel_file_path)) { - FML_LOG(ERROR) << "Could not locate kernel file."; - return; - } - - auto kernel_file = fml::OpenFile(kernel_file_path.c_str(), false, - fml::FilePermission::kRead); - - if (!kernel_file.is_valid()) { - FML_LOG(ERROR) << "Kernel file descriptor was invalid."; - return; - } - - auto kernel_mapping = std::make_unique(kernel_file); - - if (kernel_mapping->GetMapping() == nullptr) { - FML_LOG(ERROR) << "Could not setup kernel mapping."; - return; - } - - if (!root_isolate->get()->PrepareForRunningFromKernel( - std::move(kernel_mapping))) { - FML_LOG(ERROR) - << "Could not prepare to run the isolate from the kernel file."; - return; - } - } else { - if (!root_isolate->get()->PrepareForRunningFromPrecompiledCode()) { - FML_LOG(ERROR) - << "Could not prepare to run the isolate from precompiled code."; - return; - } - } +void RunDartCodeInIsolate(DartVMRef& vm_ref, + std::unique_ptr& result, + const Settings& settings, + const TaskRunners& task_runners, + std::string entrypoint, + const std::vector& args, + const std::string& fixtures_path, + fml::WeakPtr io_manager = {}); - if (root_isolate->get()->GetPhase() != DartIsolate::Phase::Ready) { - FML_LOG(ERROR) << "Isolate is in unexpected phase."; - return; - } - - if (!root_isolate->get()->Run(entrypoint, args, - settings.root_isolate_create_callback)) { - FML_LOG(ERROR) << "Could not run the method \"" << entrypoint - << "\" in the isolate."; - return; - } - - root_isolate->get()->AddIsolateShutdownCallback( - settings.root_isolate_shutdown_callback); - - result = std::move(root_isolate); -} - -static std::unique_ptr RunDartCodeInIsolate( +std::unique_ptr RunDartCodeInIsolate( DartVMRef& vm_ref, const Settings& settings, const TaskRunners& task_runners, std::string entrypoint, const std::vector& args, const std::string& fixtures_path, - fml::WeakPtr io_manager = {}) { - std::unique_ptr result; - fml::AutoResetWaitableEvent latch; - fml::TaskRunner::RunNowOrPostTask( - task_runners.GetPlatformTaskRunner(), fml::MakeCopyable([&]() mutable { - RunDartCodeInIsolate(vm_ref, result, settings, task_runners, entrypoint, - args, fixtures_path, io_manager); - latch.Signal(); - })); - latch.Wait(); - return result; -} + fml::WeakPtr io_manager = {}); } // namespace testing } // namespace flutter + +#endif // FLUTTER_TESTING_DART_ISOLATE_RUNNER_H_ From 48af239219574e4654671f46c41d95d9371f693d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 4 Mar 2020 12:14:18 -0800 Subject: [PATCH 2/2] format... --- testing/dart_isolate_runner.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/testing/dart_isolate_runner.cc b/testing/dart_isolate_runner.cc index fd1eb24508c65..6e744ab3fcce7 100644 --- a/testing/dart_isolate_runner.cc +++ b/testing/dart_isolate_runner.cc @@ -48,13 +48,13 @@ bool AutoIsolateShutdown::RunInIsolateScope(std::function closure) { } void RunDartCodeInIsolate(DartVMRef& vm_ref, - std::unique_ptr& result, - const Settings& settings, - const TaskRunners& task_runners, - std::string entrypoint, - const std::vector& args, - const std::string& fixtures_path, - fml::WeakPtr io_manager) { + std::unique_ptr& result, + const Settings& settings, + const TaskRunners& task_runners, + std::string entrypoint, + const std::vector& args, + const std::string& fixtures_path, + fml::WeakPtr io_manager) { FML_CHECK(task_runners.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); if (!vm_ref) {