未验证 提交 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
FILE: ../../../flutter/runtime/dart_isolate.cc
FILE: ../../../flutter/runtime/dart_isolate.h
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.h
FILE: ../../../flutter/runtime/dart_service_isolate_unittests.cc
......
......@@ -29,6 +29,8 @@ using UnhandledExceptionCallback =
// callback that generates the mapping from these paths.
// https://github.com/flutter/flutter/issues/26783
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 {
Settings();
......@@ -53,8 +55,10 @@ struct Settings {
MappingCallback dart_library_sources_kernel;
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::vector<std::string> dart_flags;
......
......@@ -101,18 +101,17 @@ test_fixtures("runtime_fixtures") {
fixtures = [ "fixtures/simple_main.dart" ]
}
executable("runtime_unittests") {
source_set("runtime_unittests_common") {
visibility = [ ":*" ]
testonly = true
sources = [
"dart_isolate_unittests.cc",
"dart_service_isolate_unittests.cc",
"dart_vm_unittests.cc",
"runtime_test.cc",
"runtime_test.h",
]
deps = [
public_deps = [
":libdart",
":runtime",
":runtime_fixtures",
......@@ -124,6 +123,36 @@ executable("runtime_unittests") {
"//third_party/skia",
"//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) {
ldflags = [ "-rdynamic" ]
......
......@@ -162,17 +162,8 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
tonic::DartIsolateScope scope(isolate());
if (is_root_isolate) {
if (auto task_runner = GetTaskRunners().GetUITaskRunner()) {
// 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);
}
}
SetMessageHandlingTaskRunner(GetTaskRunners().GetUITaskRunner(),
is_root_isolate);
if (tonic::LogIfError(
Dart_SetLibraryTagHandler(tonic::DartState::HandleLibraryTag))) {
......@@ -187,6 +178,23 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
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.
// Instead, this is just additional metadata for the Observatory to show the
// thread name of the isolate.
......@@ -361,6 +369,34 @@ bool DartIsolate::PrepareForRunningFromKernel(
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() {
TRACE_EVENT0("flutter", "DartIsolate::MarkIsolateRunnable");
if (phase_ != Phase::LibrariesSetup) {
......@@ -484,7 +520,6 @@ bool DartIsolate::Shutdown() {
// the isolate to shutdown as a parameter.
FML_DCHECK(Dart_CurrentIsolate() == nullptr);
Dart_EnterIsolate(vm_isolate);
shutdown_callbacks_.clear();
Dart_ShutdownIsolate();
FML_DCHECK(Dart_CurrentIsolate() == nullptr);
}
......@@ -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
// only reference returned to the caller is weak.
embedder_isolate.release();
......@@ -694,7 +731,9 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
// |Dart_IsolateShutdownCallback|
void DartIsolate::DartIsolateShutdownCallback(
std::shared_ptr<DartIsolate>* embedder_isolate) {}
std::shared_ptr<DartIsolate>* embedder_isolate) {
embedder_isolate->get()->OnShutdownCallback();
}
// |Dart_IsolateCleanupCallback|
void DartIsolate::DartIsolateCleanupCallback(
......@@ -719,6 +758,12 @@ void DartIsolate::AddIsolateShutdownCallback(fml::closure 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)
: closure_(std::move(closure)) {}
......
......@@ -5,6 +5,7 @@
#ifndef FLUTTER_RUNTIME_DART_ISOLATE_H_
#define FLUTTER_RUNTIME_DART_ISOLATE_H_
#include <memory>
#include <set>
#include <string>
......@@ -75,6 +76,14 @@ class DartIsolate : public UIDartState {
bool PrepareForRunningFromKernel(std::shared_ptr<const fml::Mapping> kernel,
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
bool Run(const std::string& entrypoint, fml::closure on_run = nullptr);
......@@ -94,6 +103,8 @@ class DartIsolate : public UIDartState {
std::weak_ptr<DartIsolate> GetWeakIsolatePtr();
fml::RefPtr<fml::TaskRunner> GetMessageHandlingTaskRunner() const;
private:
bool LoadKernel(std::shared_ptr<const fml::Mapping> mapping, bool last_piece);
......@@ -116,10 +127,14 @@ class DartIsolate : public UIDartState {
std::vector<std::shared_ptr<const fml::Mapping>> kernel_buffers_;
std::vector<std::unique_ptr<AutoFireClosure>> shutdown_callbacks_;
ChildIsolatePreparer child_isolate_preparer_ = nullptr;
fml::RefPtr<fml::TaskRunner> message_handling_task_runner_;
FML_WARN_UNUSED_RESULT
bool Initialize(Dart_Isolate isolate, bool is_root_isolate);
void SetMessageHandlingTaskRunner(fml::RefPtr<fml::TaskRunner> runner,
bool is_root_isolate);
FML_WARN_UNUSED_RESULT
bool LoadLibraries(bool is_root_isolate);
......@@ -128,6 +143,8 @@ class DartIsolate : public UIDartState {
FML_WARN_UNUSED_RESULT
bool MarkIsolateRunnable();
void OnShutdownCallback();
// |Dart_IsolateCreateCallback|
static Dart_Isolate DartIsolateCreateCallback(
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 @@
#include "flutter/fml/file.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/synchronization/count_down_latch.h"
#include "flutter/fml/synchronization/thread_annotations.h"
#include "flutter/fml/time/time_delta.h"
#include "flutter/fml/trace_event.h"
......@@ -450,4 +451,54 @@ std::shared_ptr<IsolateNameServer> DartVM::GetIsolateNameServer() const {
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
......@@ -36,17 +36,27 @@ class DartVM {
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<IsolateNameServer> GetIsolateNameServer() const;
void ShutdownAllIsolates();
private:
const Settings settings_;
std::shared_ptr<const DartVMData> vm_data_;
const std::shared_ptr<IsolateNameServer> isolate_name_server_;
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 DartIsolate;
static std::shared_ptr<DartVM> Create(
Settings settings,
......@@ -58,6 +68,10 @@ class DartVM {
DartVM(std::shared_ptr<const DartVMData> data,
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);
};
......
......@@ -114,4 +114,9 @@ std::shared_ptr<IsolateNameServer> DartVMRef::GetIsolateNameServer() {
return gVMIsolateNameServer.lock();
}
DartVM* DartVMRef::GetRunningVM() {
std::lock_guard<std::mutex> lock(gVMMutex);
return gVM.lock().get();
}
} // namespace blink
......@@ -49,6 +49,11 @@ class DartVMRef {
operator bool() const { return static_cast<bool>(vm_); }
DartVM* get() {
FML_DCHECK(vm_);
return vm_.get();
}
DartVM* operator->() {
FML_DCHECK(vm_);
return vm_.get();
......@@ -60,10 +65,15 @@ class DartVMRef {
}
private:
friend class DartIsolate;
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);
};
......
......@@ -25,3 +25,7 @@ void canRegisterNativeCallback() async {
}
void NotifyNative() native "NotifyNative";
@pragma('vm:entry-point')
void testIsolateShutdown() { }
......@@ -68,6 +68,13 @@ void RuntimeTest::SetSnapshotsAndAssets(Settings& settings) {
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 {
class KernelIsolateConfiguration : public IsolateConfiguration {
public:
KernelIsolateConfiguration(std::unique_ptr<fml::Mapping> kernel)
KernelIsolateConfiguration(std::unique_ptr<const fml::Mapping> kernel)
: kernel_(std::move(kernel)) {}
// |shell::IsolateConfiguration|
......@@ -50,7 +50,7 @@ class KernelIsolateConfiguration : public IsolateConfiguration {
}
private:
std::unique_ptr<fml::Mapping> kernel_;
std::unique_ptr<const fml::Mapping> kernel_;
FML_DISALLOW_COPY_AND_ASSIGN(KernelIsolateConfiguration);
};
......@@ -58,7 +58,8 @@ class KernelIsolateConfiguration : public IsolateConfiguration {
class KernelListIsolateConfiguration final : public IsolateConfiguration {
public:
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)) {}
// |shell::IsolateConfiguration|
......@@ -80,7 +81,7 @@ class KernelListIsolateConfiguration final : public IsolateConfiguration {
}
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);
};
......@@ -112,15 +113,15 @@ static std::vector<std::string> ParseKernelListPaths(
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,
std::shared_ptr<blink::AssetManager> asset_manager,
fml::RefPtr<fml::TaskRunner> io_worker) {
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) {
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());
auto fetch_task =
fml::MakeCopyable([asset_manager, kernel_pieces_path,
......@@ -153,6 +154,10 @@ std::unique_ptr<IsolateConfiguration> IsolateConfiguration::InferFromSettings(
return nullptr;
}
if (settings.application_kernels) {
return CreateForKernelList(settings.application_kernels());
}
if (settings.application_kernel_asset.empty() &&
settings.application_kernel_list_asset.empty()) {
FML_DLOG(ERROR) << "application_kernel_asset or "
......@@ -192,15 +197,15 @@ IsolateConfiguration::CreateForAppSnapshot() {
}
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));
}
std::unique_ptr<IsolateConfiguration> IsolateConfiguration::CreateForKernelList(
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces) {
std::vector<std::future<std::unique_ptr<fml::Mapping>>> pieces;
std::vector<std::unique_ptr<const fml::Mapping>> kernel_pieces) {
std::vector<std::future<std::unique_ptr<const fml::Mapping>>> 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());
promise.set_value(std::move(piece));
}
......@@ -208,7 +213,8 @@ 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>(
std::move(kernel_pieces));
}
......
......@@ -29,16 +29,14 @@ class IsolateConfiguration {
static std::unique_ptr<IsolateConfiguration> CreateForAppSnapshot();
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(
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(
std::vector<std::unique_ptr<fml::Mapping>> kernel_pieces);
std::vector<std::unique_ptr<const fml::Mapping>> kernel_pieces);
IsolateConfiguration();
......
......@@ -207,7 +207,7 @@ std::unique_ptr<IsolateConfiguration> CreateIsolateConfiguration(
auto blob = asset_manager.GetAsMapping(snapshot_name);
auto delta = asset_manager.GetAsMapping("kernel_delta.bin");
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(delta));
return IsolateConfiguration::CreateForKernelList(std::move(kernels));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册