未验证 提交 b59c4436 编写于 作者: C Chinmay Garde 提交者: GitHub

Enable shutting down all root isolates in a VM. (#8402)

上级 9acdf183
...@@ -374,6 +374,7 @@ FILE: ../../../flutter/lib/ui/window/window.h ...@@ -374,6 +374,7 @@ FILE: ../../../flutter/lib/ui/window/window.h
FILE: ../../../flutter/runtime/dart_isolate.cc FILE: ../../../flutter/runtime/dart_isolate.cc
FILE: ../../../flutter/runtime/dart_isolate.h FILE: ../../../flutter/runtime/dart_isolate.h
FILE: ../../../flutter/runtime/dart_isolate_unittests.cc FILE: ../../../flutter/runtime/dart_isolate_unittests.cc
FILE: ../../../flutter/runtime/dart_lifecycle_unittests.cc
FILE: ../../../flutter/runtime/dart_service_isolate.cc FILE: ../../../flutter/runtime/dart_service_isolate.cc
FILE: ../../../flutter/runtime/dart_service_isolate.h FILE: ../../../flutter/runtime/dart_service_isolate.h
FILE: ../../../flutter/runtime/dart_service_isolate_unittests.cc FILE: ../../../flutter/runtime/dart_service_isolate_unittests.cc
......
...@@ -29,6 +29,8 @@ using UnhandledExceptionCallback = ...@@ -29,6 +29,8 @@ using UnhandledExceptionCallback =
// callback that generates the mapping from these paths. // callback that generates the mapping from these paths.
// https://github.com/flutter/flutter/issues/26783 // https://github.com/flutter/flutter/issues/26783
using MappingCallback = std::function<std::unique_ptr<fml::Mapping>(void)>; using MappingCallback = std::function<std::unique_ptr<fml::Mapping>(void)>;
using MappingsCallback =
std::function<std::vector<std::unique_ptr<const fml::Mapping>>(void)>;
struct Settings { struct Settings {
Settings(); Settings();
...@@ -53,8 +55,10 @@ struct Settings { ...@@ -53,8 +55,10 @@ struct Settings {
MappingCallback dart_library_sources_kernel; MappingCallback dart_library_sources_kernel;
std::string application_library_path; std::string application_library_path;
std::string application_kernel_asset;
std::string application_kernel_list_asset; std::string application_kernel_asset; // deprecated
std::string application_kernel_list_asset; // deprecated
MappingsCallback application_kernels;
std::string temp_directory_path; std::string temp_directory_path;
std::vector<std::string> dart_flags; std::vector<std::string> dart_flags;
......
...@@ -101,18 +101,17 @@ test_fixtures("runtime_fixtures") { ...@@ -101,18 +101,17 @@ test_fixtures("runtime_fixtures") {
fixtures = [ "fixtures/simple_main.dart" ] fixtures = [ "fixtures/simple_main.dart" ]
} }
executable("runtime_unittests") { source_set("runtime_unittests_common") {
visibility = [ ":*" ]
testonly = true testonly = true
sources = [ sources = [
"dart_isolate_unittests.cc",
"dart_service_isolate_unittests.cc",
"dart_vm_unittests.cc",
"runtime_test.cc", "runtime_test.cc",
"runtime_test.h", "runtime_test.h",
] ]
deps = [ public_deps = [
":libdart", ":libdart",
":runtime", ":runtime",
":runtime_fixtures", ":runtime_fixtures",
...@@ -124,6 +123,36 @@ executable("runtime_unittests") { ...@@ -124,6 +123,36 @@ executable("runtime_unittests") {
"//third_party/skia", "//third_party/skia",
"//third_party/tonic", "//third_party/tonic",
] ]
}
executable("runtime_unittests") {
testonly = true
sources = [
"dart_isolate_unittests.cc",
"dart_service_isolate_unittests.cc",
"dart_vm_unittests.cc",
]
deps = [
":runtime_unittests_common",
]
if (is_linux) {
ldflags = [ "-rdynamic" ]
}
}
executable("runtime_lifecycle_unittests") {
testonly = true
sources = [
"dart_lifecycle_unittests.cc",
]
deps = [
":runtime_unittests_common",
]
if (is_linux) { if (is_linux) {
ldflags = [ "-rdynamic" ] ldflags = [ "-rdynamic" ]
......
...@@ -162,17 +162,8 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) { ...@@ -162,17 +162,8 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
tonic::DartIsolateScope scope(isolate()); tonic::DartIsolateScope scope(isolate());
if (is_root_isolate) { SetMessageHandlingTaskRunner(GetTaskRunners().GetUITaskRunner(),
if (auto task_runner = GetTaskRunners().GetUITaskRunner()) { is_root_isolate);
// Isolates may not have any particular thread affinity. Only initialize
// the task dispatcher if a task runner is explicitly specified.
tonic::DartMessageHandler::TaskDispatcher dispatcher =
[task_runner](std::function<void()> task) {
task_runner->PostTask(task);
};
message_handler().Initialize(dispatcher);
}
}
if (tonic::LogIfError( if (tonic::LogIfError(
Dart_SetLibraryTagHandler(tonic::DartState::HandleLibraryTag))) { Dart_SetLibraryTagHandler(tonic::DartState::HandleLibraryTag))) {
...@@ -187,6 +178,23 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) { ...@@ -187,6 +178,23 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
return true; return true;
} }
fml::RefPtr<fml::TaskRunner> DartIsolate::GetMessageHandlingTaskRunner() const {
return message_handling_task_runner_;
}
void DartIsolate::SetMessageHandlingTaskRunner(
fml::RefPtr<fml::TaskRunner> runner,
bool is_root_isolate) {
if (!is_root_isolate || !runner) {
return;
}
message_handling_task_runner_ = runner;
message_handler().Initialize(
[runner](std::function<void()> task) { runner->PostTask(task); });
}
// Updating thread names here does not change the underlying OS thread names. // Updating thread names here does not change the underlying OS thread names.
// Instead, this is just additional metadata for the Observatory to show the // Instead, this is just additional metadata for the Observatory to show the
// thread name of the isolate. // thread name of the isolate.
...@@ -361,6 +369,34 @@ bool DartIsolate::PrepareForRunningFromKernel( ...@@ -361,6 +369,34 @@ bool DartIsolate::PrepareForRunningFromKernel(
return true; return true;
} }
FML_WARN_UNUSED_RESULT
bool DartIsolate::PrepareForRunningFromKernels(
std::vector<std::shared_ptr<const fml::Mapping>> kernels) {
const auto count = kernels.size();
if (count == 0) {
return false;
}
for (size_t i = 0; i < count; ++i) {
bool last = (i == (count - 1));
if (!PrepareForRunningFromKernel(kernels[i], last)) {
return false;
}
}
return true;
}
FML_WARN_UNUSED_RESULT
bool DartIsolate::PrepareForRunningFromKernels(
std::vector<std::unique_ptr<const fml::Mapping>> kernels) {
std::vector<std::shared_ptr<const fml::Mapping>> shared_kernels;
for (auto& kernel : kernels) {
shared_kernels.emplace_back(std::move(kernel));
}
return PrepareForRunningFromKernels(shared_kernels);
}
bool DartIsolate::MarkIsolateRunnable() { bool DartIsolate::MarkIsolateRunnable() {
TRACE_EVENT0("flutter", "DartIsolate::MarkIsolateRunnable"); TRACE_EVENT0("flutter", "DartIsolate::MarkIsolateRunnable");
if (phase_ != Phase::LibrariesSetup) { if (phase_ != Phase::LibrariesSetup) {
...@@ -484,7 +520,6 @@ bool DartIsolate::Shutdown() { ...@@ -484,7 +520,6 @@ bool DartIsolate::Shutdown() {
// the isolate to shutdown as a parameter. // the isolate to shutdown as a parameter.
FML_DCHECK(Dart_CurrentIsolate() == nullptr); FML_DCHECK(Dart_CurrentIsolate() == nullptr);
Dart_EnterIsolate(vm_isolate); Dart_EnterIsolate(vm_isolate);
shutdown_callbacks_.clear();
Dart_ShutdownIsolate(); Dart_ShutdownIsolate();
FML_DCHECK(Dart_CurrentIsolate() == nullptr); FML_DCHECK(Dart_CurrentIsolate() == nullptr);
} }
...@@ -686,6 +721,8 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair( ...@@ -686,6 +721,8 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
} }
} }
DartVMRef::GetRunningVM()->RegisterActiveIsolate(*embedder_isolate);
// The ownership of the embedder object is controlled by the Dart VM. So the // The ownership of the embedder object is controlled by the Dart VM. So the
// only reference returned to the caller is weak. // only reference returned to the caller is weak.
embedder_isolate.release(); embedder_isolate.release();
...@@ -694,7 +731,9 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair( ...@@ -694,7 +731,9 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
// |Dart_IsolateShutdownCallback| // |Dart_IsolateShutdownCallback|
void DartIsolate::DartIsolateShutdownCallback( void DartIsolate::DartIsolateShutdownCallback(
std::shared_ptr<DartIsolate>* embedder_isolate) {} std::shared_ptr<DartIsolate>* embedder_isolate) {
embedder_isolate->get()->OnShutdownCallback();
}
// |Dart_IsolateCleanupCallback| // |Dart_IsolateCleanupCallback|
void DartIsolate::DartIsolateCleanupCallback( void DartIsolate::DartIsolateCleanupCallback(
...@@ -719,6 +758,12 @@ void DartIsolate::AddIsolateShutdownCallback(fml::closure closure) { ...@@ -719,6 +758,12 @@ void DartIsolate::AddIsolateShutdownCallback(fml::closure closure) {
std::make_unique<AutoFireClosure>(std::move(closure))); std::make_unique<AutoFireClosure>(std::move(closure)));
} }
void DartIsolate::OnShutdownCallback() {
shutdown_callbacks_.clear();
DartVMRef::GetRunningVM()->UnregisterActiveIsolate(
std::static_pointer_cast<DartIsolate>(shared_from_this()));
}
DartIsolate::AutoFireClosure::AutoFireClosure(fml::closure closure) DartIsolate::AutoFireClosure::AutoFireClosure(fml::closure closure)
: closure_(std::move(closure)) {} : closure_(std::move(closure)) {}
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef FLUTTER_RUNTIME_DART_ISOLATE_H_ #ifndef FLUTTER_RUNTIME_DART_ISOLATE_H_
#define FLUTTER_RUNTIME_DART_ISOLATE_H_ #define FLUTTER_RUNTIME_DART_ISOLATE_H_
#include <memory>
#include <set> #include <set>
#include <string> #include <string>
...@@ -75,6 +76,14 @@ class DartIsolate : public UIDartState { ...@@ -75,6 +76,14 @@ class DartIsolate : public UIDartState {
bool PrepareForRunningFromKernel(std::shared_ptr<const fml::Mapping> kernel, bool PrepareForRunningFromKernel(std::shared_ptr<const fml::Mapping> kernel,
bool last_piece = true); bool last_piece = true);
FML_WARN_UNUSED_RESULT
bool PrepareForRunningFromKernels(
std::vector<std::shared_ptr<const fml::Mapping>> kernels);
FML_WARN_UNUSED_RESULT
bool PrepareForRunningFromKernels(
std::vector<std::unique_ptr<const fml::Mapping>> kernels);
FML_WARN_UNUSED_RESULT FML_WARN_UNUSED_RESULT
bool Run(const std::string& entrypoint, fml::closure on_run = nullptr); bool Run(const std::string& entrypoint, fml::closure on_run = nullptr);
...@@ -94,6 +103,8 @@ class DartIsolate : public UIDartState { ...@@ -94,6 +103,8 @@ class DartIsolate : public UIDartState {
std::weak_ptr<DartIsolate> GetWeakIsolatePtr(); std::weak_ptr<DartIsolate> GetWeakIsolatePtr();
fml::RefPtr<fml::TaskRunner> GetMessageHandlingTaskRunner() const;
private: private:
bool LoadKernel(std::shared_ptr<const fml::Mapping> mapping, bool last_piece); bool LoadKernel(std::shared_ptr<const fml::Mapping> mapping, bool last_piece);
...@@ -116,10 +127,14 @@ class DartIsolate : public UIDartState { ...@@ -116,10 +127,14 @@ class DartIsolate : public UIDartState {
std::vector<std::shared_ptr<const fml::Mapping>> kernel_buffers_; std::vector<std::shared_ptr<const fml::Mapping>> kernel_buffers_;
std::vector<std::unique_ptr<AutoFireClosure>> shutdown_callbacks_; std::vector<std::unique_ptr<AutoFireClosure>> shutdown_callbacks_;
ChildIsolatePreparer child_isolate_preparer_ = nullptr; ChildIsolatePreparer child_isolate_preparer_ = nullptr;
fml::RefPtr<fml::TaskRunner> message_handling_task_runner_;
FML_WARN_UNUSED_RESULT FML_WARN_UNUSED_RESULT
bool Initialize(Dart_Isolate isolate, bool is_root_isolate); bool Initialize(Dart_Isolate isolate, bool is_root_isolate);
void SetMessageHandlingTaskRunner(fml::RefPtr<fml::TaskRunner> runner,
bool is_root_isolate);
FML_WARN_UNUSED_RESULT FML_WARN_UNUSED_RESULT
bool LoadLibraries(bool is_root_isolate); bool LoadLibraries(bool is_root_isolate);
...@@ -128,6 +143,8 @@ class DartIsolate : public UIDartState { ...@@ -128,6 +143,8 @@ class DartIsolate : public UIDartState {
FML_WARN_UNUSED_RESULT FML_WARN_UNUSED_RESULT
bool MarkIsolateRunnable(); bool MarkIsolateRunnable();
void OnShutdownCallback();
// |Dart_IsolateCreateCallback| // |Dart_IsolateCreateCallback|
static Dart_Isolate DartIsolateCreateCallback( static Dart_Isolate DartIsolateCreateCallback(
const char* advisory_script_uri, const char* advisory_script_uri,
......
// 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/common/task_runners.h"
#include "flutter/fml/paths.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/runtime/dart_vm_lifecycle.h"
#include "flutter/runtime/runtime_test.h"
namespace blink {
namespace testing {
using DartLifecycleTest = RuntimeTest;
TEST_F(DartLifecycleTest, CanStartAndShutdownVM) {
auto settings = CreateSettingsForFixture();
settings.leak_vm = false;
settings.enable_observatory = false;
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
{
auto vm_ref = DartVMRef::Create(settings);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
}
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
TEST_F(DartLifecycleTest, CanStartAndShutdownVMOverAndOver) {
auto settings = CreateSettingsForFixture();
settings.leak_vm = false;
settings.enable_observatory = false;
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
auto count = DartVM::GetVMLaunchCount();
for (size_t i = 0; i < 10; i++) {
auto vm_ref = DartVMRef::Create(settings);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
ASSERT_EQ(DartVM::GetVMLaunchCount(), count + 1);
count = DartVM::GetVMLaunchCount();
}
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
static void CreateAndRunRootIsolate(
std::shared_ptr<DartIsolate>& isolate_result,
const Settings& settings,
const DartVMData& vm,
fml::RefPtr<fml::TaskRunner> task_runner,
std::string entrypoint) {
FML_CHECK(entrypoint.size() > 0);
TaskRunners runners("io.flutter.test", task_runner, task_runner, task_runner,
task_runner);
auto isolate_weak = DartIsolate::CreateRootIsolate(
vm.GetSettings(), // settings
vm.GetIsolateSnapshot(), // isolate_snapshot
vm.GetSharedSnapshot(), // shared_snapshot
runners, // task_runners
{}, // window
{}, // snapshot_delegate
{}, // io_manager
"main.dart", // advisory_script_uri
entrypoint.c_str(), // advisory_script_entrypoint
nullptr // flags
);
auto isolate = isolate_weak.lock();
if (!isolate) {
FML_LOG(ERROR) << "Could not create valid isolate.";
return;
}
if (DartVM::IsRunningPrecompiledCode()) {
if (!isolate->PrepareForRunningFromPrecompiledCode()) {
FML_LOG(ERROR)
<< "Could not prepare to run the isolate from precompiled code.";
return;
}
} else {
if (!isolate->PrepareForRunningFromKernels(
settings.application_kernels())) {
FML_LOG(ERROR) << "Could not prepare isolate from application kernels.";
return;
}
}
if (isolate->GetPhase() != DartIsolate::Phase::Ready) {
FML_LOG(ERROR) << "Isolate was not ready.";
return;
}
if (!isolate->Run(entrypoint, settings.root_isolate_create_callback)) {
FML_LOG(ERROR) << "Could not run entrypoint: " << entrypoint << ".";
return;
}
if (isolate->GetPhase() != DartIsolate::Phase::Running) {
FML_LOG(ERROR) << "Isolate was not Running.";
return;
}
isolate_result = isolate;
}
static std::shared_ptr<DartIsolate> CreateAndRunRootIsolate(
const Settings& settings,
const DartVMData& vm,
fml::RefPtr<fml::TaskRunner> task_runner,
std::string entrypoint) {
fml::AutoResetWaitableEvent latch;
std::shared_ptr<DartIsolate> isolate;
fml::TaskRunner::RunNowOrPostTask(task_runner, [&]() {
CreateAndRunRootIsolate(isolate, settings, vm, task_runner, entrypoint);
latch.Signal();
});
latch.Wait();
return isolate;
}
TEST_F(DartLifecycleTest, ShuttingDownTheVMShutsDownTheIsolate) {
auto settings = CreateSettingsForFixture();
settings.leak_vm = false;
settings.enable_observatory = false;
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
{
auto vm_ref = DartVMRef::Create(settings);
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
ASSERT_EQ(vm_ref->GetIsolateCount(), 0u);
auto isolate =
CreateAndRunRootIsolate(settings, *vm_ref.GetVMData(),
GetThreadTaskRunner(), "testIsolateShutdown");
ASSERT_TRUE(isolate);
ASSERT_EQ(vm_ref->GetIsolateCount(), 1u);
vm_ref->ShutdownAllIsolates();
ASSERT_EQ(vm_ref->GetIsolateCount(), 0u);
}
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
}
} // namespace testing
} // namespace blink
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "flutter/fml/file.h" #include "flutter/fml/file.h"
#include "flutter/fml/logging.h" #include "flutter/fml/logging.h"
#include "flutter/fml/mapping.h" #include "flutter/fml/mapping.h"
#include "flutter/fml/synchronization/count_down_latch.h"
#include "flutter/fml/synchronization/thread_annotations.h" #include "flutter/fml/synchronization/thread_annotations.h"
#include "flutter/fml/time/time_delta.h" #include "flutter/fml/time/time_delta.h"
#include "flutter/fml/trace_event.h" #include "flutter/fml/trace_event.h"
...@@ -450,4 +451,54 @@ std::shared_ptr<IsolateNameServer> DartVM::GetIsolateNameServer() const { ...@@ -450,4 +451,54 @@ std::shared_ptr<IsolateNameServer> DartVM::GetIsolateNameServer() const {
return isolate_name_server_; return isolate_name_server_;
} }
size_t DartVM::GetIsolateCount() const {
std::lock_guard<std::mutex> lock(active_isolates_mutex_);
return active_isolates_.size();
}
void DartVM::ShutdownAllIsolates() {
std::set<std::shared_ptr<DartIsolate>> isolates_to_shutdown;
// We may be shutting down isolates on the current thread. Shutting down the
// isolate calls the shutdown callback which removes the entry from the
// active isolate. The lock must be obtained to mutate that entry. To avoid a
// deadlock, collect the isolate is a seprate collection.
{
std::lock_guard<std::mutex> lock(active_isolates_mutex_);
for (const auto& active_isolate : active_isolates_) {
if (auto task_runner = active_isolate->GetMessageHandlingTaskRunner()) {
isolates_to_shutdown.insert(active_isolate);
}
}
}
fml::CountDownLatch latch(isolates_to_shutdown.size());
for (const auto& isolate : isolates_to_shutdown) {
fml::TaskRunner::RunNowOrPostTask(
isolate->GetMessageHandlingTaskRunner(), [&latch, isolate]() {
if (!isolate || !isolate->Shutdown()) {
FML_LOG(ERROR) << "Could not shutdown isolate.";
}
latch.CountDown();
});
}
latch.Wait();
}
void DartVM::RegisterActiveIsolate(std::shared_ptr<DartIsolate> isolate) {
if (!isolate) {
return;
}
std::lock_guard<std::mutex> lock(active_isolates_mutex_);
active_isolates_.insert(isolate);
}
void DartVM::UnregisterActiveIsolate(std::shared_ptr<DartIsolate> isolate) {
if (!isolate) {
return;
}
std::lock_guard<std::mutex> lock(active_isolates_mutex_);
active_isolates_.erase(isolate);
}
} // namespace blink } // namespace blink
...@@ -36,17 +36,27 @@ class DartVM { ...@@ -36,17 +36,27 @@ class DartVM {
std::shared_ptr<const DartVMData> GetVMData() const; std::shared_ptr<const DartVMData> GetVMData() const;
// This accessor is racy and only meant to the used in tests where there is a
// consistent threading mode.
size_t GetIsolateCount() const;
std::shared_ptr<ServiceProtocol> GetServiceProtocol() const; std::shared_ptr<ServiceProtocol> GetServiceProtocol() const;
std::shared_ptr<IsolateNameServer> GetIsolateNameServer() const; std::shared_ptr<IsolateNameServer> GetIsolateNameServer() const;
void ShutdownAllIsolates();
private: private:
const Settings settings_; const Settings settings_;
std::shared_ptr<const DartVMData> vm_data_; std::shared_ptr<const DartVMData> vm_data_;
const std::shared_ptr<IsolateNameServer> isolate_name_server_; const std::shared_ptr<IsolateNameServer> isolate_name_server_;
const std::shared_ptr<ServiceProtocol> service_protocol_; const std::shared_ptr<ServiceProtocol> service_protocol_;
mutable std::mutex active_isolates_mutex_;
std::set<std::shared_ptr<DartIsolate>> active_isolates_
FML_GUARDED_BY(active_isolates_mutex_);
friend class DartVMRef; friend class DartVMRef;
friend class DartIsolate;
static std::shared_ptr<DartVM> Create( static std::shared_ptr<DartVM> Create(
Settings settings, Settings settings,
...@@ -58,6 +68,10 @@ class DartVM { ...@@ -58,6 +68,10 @@ class DartVM {
DartVM(std::shared_ptr<const DartVMData> data, DartVM(std::shared_ptr<const DartVMData> data,
std::shared_ptr<IsolateNameServer> isolate_name_server); std::shared_ptr<IsolateNameServer> isolate_name_server);
void RegisterActiveIsolate(std::shared_ptr<DartIsolate> isolate);
void UnregisterActiveIsolate(std::shared_ptr<DartIsolate> isolate);
FML_DISALLOW_COPY_AND_ASSIGN(DartVM); FML_DISALLOW_COPY_AND_ASSIGN(DartVM);
}; };
......
...@@ -114,4 +114,9 @@ std::shared_ptr<IsolateNameServer> DartVMRef::GetIsolateNameServer() { ...@@ -114,4 +114,9 @@ std::shared_ptr<IsolateNameServer> DartVMRef::GetIsolateNameServer() {
return gVMIsolateNameServer.lock(); return gVMIsolateNameServer.lock();
} }
DartVM* DartVMRef::GetRunningVM() {
std::lock_guard<std::mutex> lock(gVMMutex);
return gVM.lock().get();
}
} // namespace blink } // namespace blink
...@@ -49,6 +49,11 @@ class DartVMRef { ...@@ -49,6 +49,11 @@ class DartVMRef {
operator bool() const { return static_cast<bool>(vm_); } operator bool() const { return static_cast<bool>(vm_); }
DartVM* get() {
FML_DCHECK(vm_);
return vm_.get();
}
DartVM* operator->() { DartVM* operator->() {
FML_DCHECK(vm_); FML_DCHECK(vm_);
return vm_.get(); return vm_.get();
...@@ -60,10 +65,15 @@ class DartVMRef { ...@@ -60,10 +65,15 @@ class DartVMRef {
} }
private: private:
friend class DartIsolate;
std::shared_ptr<DartVM> vm_; std::shared_ptr<DartVM> vm_;
DartVMRef(std::shared_ptr<DartVM> vm); DartVMRef(std::shared_ptr<DartVM> vm);
// Only used by Dart Isolate to register itself with the VM.
static DartVM* GetRunningVM();
FML_DISALLOW_COPY_AND_ASSIGN(DartVMRef); FML_DISALLOW_COPY_AND_ASSIGN(DartVMRef);
}; };
......
...@@ -25,3 +25,7 @@ void canRegisterNativeCallback() async { ...@@ -25,3 +25,7 @@ void canRegisterNativeCallback() async {
} }
void NotifyNative() native "NotifyNative"; void NotifyNative() native "NotifyNative";
@pragma('vm:entry-point')
void testIsolateShutdown() { }
...@@ -68,6 +68,13 @@ void RuntimeTest::SetSnapshotsAndAssets(Settings& settings) { ...@@ -68,6 +68,13 @@ void RuntimeTest::SetSnapshotsAndAssets(Settings& settings) {
return GetMapping(assets_dir_, "isolate_snapshot_instr", true); return GetMapping(assets_dir_, "isolate_snapshot_instr", true);
}; };
} }
} else {
settings.application_kernels = [this]() {
std::vector<std::unique_ptr<const fml::Mapping>> kernel_mappings;
kernel_mappings.emplace_back(
GetMapping(assets_dir_, "kernel_blob.bin", false));
return kernel_mappings;
};
} }
} }
......
...@@ -38,7 +38,7 @@ class AppSnapshotIsolateConfiguration final : public IsolateConfiguration { ...@@ -38,7 +38,7 @@ class AppSnapshotIsolateConfiguration final : public IsolateConfiguration {
class KernelIsolateConfiguration : public IsolateConfiguration { class KernelIsolateConfiguration : public IsolateConfiguration {
public: public:
KernelIsolateConfiguration(std::unique_ptr<fml::Mapping> kernel) KernelIsolateConfiguration(std::unique_ptr<const fml::Mapping> kernel)
: kernel_(std::move(kernel)) {} : kernel_(std::move(kernel)) {}
// |shell::IsolateConfiguration| // |shell::IsolateConfiguration|
...@@ -50,7 +50,7 @@ class KernelIsolateConfiguration : public IsolateConfiguration { ...@@ -50,7 +50,7 @@ class KernelIsolateConfiguration : public IsolateConfiguration {
} }
private: private:
std::unique_ptr<fml::Mapping> kernel_; std::unique_ptr<const fml::Mapping> kernel_;
FML_DISALLOW_COPY_AND_ASSIGN(KernelIsolateConfiguration); FML_DISALLOW_COPY_AND_ASSIGN(KernelIsolateConfiguration);
}; };
...@@ -58,7 +58,8 @@ class KernelIsolateConfiguration : public IsolateConfiguration { ...@@ -58,7 +58,8 @@ class KernelIsolateConfiguration : public IsolateConfiguration {
class KernelListIsolateConfiguration final : public IsolateConfiguration { class KernelListIsolateConfiguration final : public IsolateConfiguration {
public: public:
KernelListIsolateConfiguration( KernelListIsolateConfiguration(
std::vector<std::future<std::unique_ptr<fml::Mapping>>> kernel_pieces) std::vector<std::future<std::unique_ptr<const fml::Mapping>>>
kernel_pieces)
: kernel_pieces_(std::move(kernel_pieces)) {} : kernel_pieces_(std::move(kernel_pieces)) {}
// |shell::IsolateConfiguration| // |shell::IsolateConfiguration|
...@@ -80,7 +81,7 @@ class KernelListIsolateConfiguration final : public IsolateConfiguration { ...@@ -80,7 +81,7 @@ class KernelListIsolateConfiguration final : public IsolateConfiguration {
} }
private: private:
std::vector<std::future<std::unique_ptr<fml::Mapping>>> kernel_pieces_; std::vector<std::future<std::unique_ptr<const fml::Mapping>>> kernel_pieces_;
FML_DISALLOW_COPY_AND_ASSIGN(KernelListIsolateConfiguration); FML_DISALLOW_COPY_AND_ASSIGN(KernelListIsolateConfiguration);
}; };
...@@ -112,15 +113,15 @@ static std::vector<std::string> ParseKernelListPaths( ...@@ -112,15 +113,15 @@ static std::vector<std::string> ParseKernelListPaths(
return kernel_pieces_paths; return kernel_pieces_paths;
} }
static std::vector<std::future<std::unique_ptr<fml::Mapping>>> static std::vector<std::future<std::unique_ptr<const fml::Mapping>>>
PrepareKernelMappings(std::vector<std::string> kernel_pieces_paths, PrepareKernelMappings(std::vector<std::string> kernel_pieces_paths,
std::shared_ptr<blink::AssetManager> asset_manager, std::shared_ptr<blink::AssetManager> asset_manager,
fml::RefPtr<fml::TaskRunner> io_worker) { fml::RefPtr<fml::TaskRunner> io_worker) {
FML_DCHECK(asset_manager); FML_DCHECK(asset_manager);
std::vector<std::future<std::unique_ptr<fml::Mapping>>> fetch_futures; std::vector<std::future<std::unique_ptr<const fml::Mapping>>> fetch_futures;
for (const auto& kernel_pieces_path : kernel_pieces_paths) { for (const auto& kernel_pieces_path : kernel_pieces_paths) {
std::promise<std::unique_ptr<fml::Mapping>> fetch_promise; std::promise<std::unique_ptr<const fml::Mapping>> fetch_promise;
fetch_futures.push_back(fetch_promise.get_future()); fetch_futures.push_back(fetch_promise.get_future());
auto fetch_task = auto fetch_task =
fml::MakeCopyable([asset_manager, kernel_pieces_path, fml::MakeCopyable([asset_manager, kernel_pieces_path,
...@@ -153,6 +154,10 @@ std::unique_ptr<IsolateConfiguration> IsolateConfiguration::InferFromSettings( ...@@ -153,6 +154,10 @@ std::unique_ptr<IsolateConfiguration> IsolateConfiguration::InferFromSettings(
return nullptr; return nullptr;
} }
if (settings.application_kernels) {
return CreateForKernelList(settings.application_kernels());
}
if (settings.application_kernel_asset.empty() && if (settings.application_kernel_asset.empty() &&
settings.application_kernel_list_asset.empty()) { settings.application_kernel_list_asset.empty()) {
FML_DLOG(ERROR) << "application_kernel_asset or " FML_DLOG(ERROR) << "application_kernel_asset or "
...@@ -192,15 +197,15 @@ IsolateConfiguration::CreateForAppSnapshot() { ...@@ -192,15 +197,15 @@ IsolateConfiguration::CreateForAppSnapshot() {
} }
std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernel( std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernel(
std::unique_ptr<fml::Mapping> kernel) { std::unique_ptr<const fml::Mapping> kernel) {
return std::make_unique<KernelIsolateConfiguration>(std::move(kernel)); return std::make_unique<KernelIsolateConfiguration>(std::move(kernel));
} }
std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList( std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList(
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces) { std::vector<std::unique_ptr<const fml::Mapping>> kernel_pieces) {
std::vector<std::future<std::unique_ptr<fml::Mapping>>> pieces; std::vector<std::future<std::unique_ptr<const fml::Mapping>>> pieces;
for (auto& piece : kernel_pieces) { for (auto& piece : kernel_pieces) {
std::promise<std::unique_ptr<fml::Mapping>> promise; std::promise<std::unique_ptr<const fml::Mapping>> promise;
pieces.push_back(promise.get_future()); pieces.push_back(promise.get_future());
promise.set_value(std::move(piece)); promise.set_value(std::move(piece));
} }
...@@ -208,7 +213,8 @@ std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList( ...@@ -208,7 +213,8 @@ std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList(
} }
std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList( std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList(
std::vector<std::future<std::unique_ptr<fml::Mapping>>> kernel_pieces) { std::vector<std::future<std::unique_ptr<const fml::Mapping>>>
kernel_pieces) {
return std::make_unique<KernelListIsolateConfiguration>( return std::make_unique<KernelListIsolateConfiguration>(
std::move(kernel_pieces)); std::move(kernel_pieces));
} }
......
...@@ -29,16 +29,14 @@ class IsolateConfiguration { ...@@ -29,16 +29,14 @@ class IsolateConfiguration {
static std::unique_ptr<IsolateConfiguration> CreateForAppSnapshot(); static std::unique_ptr<IsolateConfiguration> CreateForAppSnapshot();
static std::unique_ptr<IsolateConfiguration> CreateForKernel( static std::unique_ptr<IsolateConfiguration> CreateForKernel(
std::unique_ptr<fml::Mapping> kernel); std::unique_ptr<const fml::Mapping> kernel);
static std::unique_ptr<IsolateConfiguration> CreateForKernelList( static std::unique_ptr<IsolateConfiguration> CreateForKernelList(
std::vector<std::future<std::unique_ptr<fml::Mapping>>> kernel_pieces); std::vector<std::future<std::unique_ptr<const fml::Mapping>>>
kernel_pieces);
// TODO(chinmaygarde): Remove this variant in favor of the one using futures
// for parallelizing asset loads. This one is in place for API compatibility
// till Android is updated.
static std::unique_ptr<IsolateConfiguration> CreateForKernelList( static std::unique_ptr<IsolateConfiguration> CreateForKernelList(
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces); std::vector<std::unique_ptr<const fml::Mapping>> kernel_pieces);
IsolateConfiguration(); IsolateConfiguration();
......
...@@ -207,7 +207,7 @@ std::unique_ptr<IsolateConfiguration> CreateIsolateConfiguration( ...@@ -207,7 +207,7 @@ std::unique_ptr<IsolateConfiguration> CreateIsolateConfiguration(
auto blob = asset_manager.GetAsMapping(snapshot_name); auto blob = asset_manager.GetAsMapping(snapshot_name);
auto delta = asset_manager.GetAsMapping("kernel_delta.bin"); auto delta = asset_manager.GetAsMapping("kernel_delta.bin");
if (blob && delta) { if (blob && delta) {
std::vector<std::unique_ptr<fml::Mapping>> kernels; std::vector<std::unique_ptr<const fml::Mapping>> kernels;
kernels.emplace_back(std::move(blob)); kernels.emplace_back(std::move(blob));
kernels.emplace_back(std::move(delta)); kernels.emplace_back(std::move(delta));
return IsolateConfiguration::CreateForKernelList(std::move(kernels)); return IsolateConfiguration::CreateForKernelList(std::move(kernels));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册