mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
f6900001eb
Remove dead shared snapshot arguments to Dart_CreateIsolateGroup. 6a65ea9cad4b [vm] Remove shared snapshot and reused instructions features. db8370e36147 [gardening] Fix frontend-server dartdevc windows test. 4601bd7bffea Modified supertype check error message to be more descriptive. 0449905e2de6 [CFE] Add a serialization-and-unserialization step to strong test c8b903c2f94f Update CHANGELOG.md 2a12a13d9684 [Test] Skips emit_aot_size_info_flag_test on crossword. b26127fe01a5 [cfe] Add reachability test skeleton
128 lines
4.3 KiB
C++
128 lines
4.3 KiB
C++
// 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/runtime/dart_vm_lifecycle.h"
|
|
|
|
#include <mutex>
|
|
|
|
namespace flutter {
|
|
|
|
// We need to explicitly put the constructor and destructor of the DartVM in the
|
|
// critical section. All accesses (not just const members) to the global VM
|
|
// object weak pointer are behind this mutex.
|
|
static std::mutex gVMMutex;
|
|
static std::weak_ptr<DartVM> gVM;
|
|
static std::shared_ptr<DartVM>* gVMLeak;
|
|
|
|
// We are going to be modifying more than just the control blocks of the
|
|
// following weak pointers (in the |Create| case where an old VM could not be
|
|
// reused). Ideally, we would use |std::atomic<std::weak_ptr<T>>| specialization
|
|
// but that is only available since C++20. We don't expect contention on these
|
|
// locks so we just use one mutex for all.
|
|
static std::mutex gVMDependentsMutex;
|
|
static std::weak_ptr<const DartVMData> gVMData;
|
|
static std::weak_ptr<ServiceProtocol> gVMServiceProtocol;
|
|
static std::weak_ptr<IsolateNameServer> gVMIsolateNameServer;
|
|
|
|
DartVMRef::DartVMRef(std::shared_ptr<DartVM> vm) : vm_(vm) {}
|
|
|
|
DartVMRef::DartVMRef(DartVMRef&& other) = default;
|
|
|
|
DartVMRef::~DartVMRef() {
|
|
if (!vm_) {
|
|
// If there is no valid VM (possible via a move), there is no way that the
|
|
// decrement on the shared pointer can cause a collection. Avoid acquiring
|
|
// the lifecycle lock in this case. This is just working around a
|
|
// pessimization and not required for correctness.
|
|
return;
|
|
}
|
|
std::scoped_lock lifecycle_lock(gVMMutex);
|
|
vm_.reset();
|
|
}
|
|
|
|
DartVMRef DartVMRef::Create(Settings settings,
|
|
fml::RefPtr<DartSnapshot> vm_snapshot,
|
|
fml::RefPtr<DartSnapshot> isolate_snapshot) {
|
|
std::scoped_lock lifecycle_lock(gVMMutex);
|
|
|
|
if (!settings.leak_vm) {
|
|
FML_CHECK(!gVMLeak)
|
|
<< "Launch settings indicated that the VM should shut down in the "
|
|
"process when done but a previous launch asked the VM to leak in "
|
|
"the same process. For proper VM shutdown, all VM launches must "
|
|
"indicate that they should shut down when done.";
|
|
}
|
|
|
|
// If there is already a running VM in the process, grab a strong reference to
|
|
// it.
|
|
if (auto vm = gVM.lock()) {
|
|
FML_DLOG(WARNING) << "Attempted to create a VM in a process where one was "
|
|
"already running. Ignoring arguments for current VM "
|
|
"create call and reusing the old VM.";
|
|
// There was already a running VM in the process,
|
|
return DartVMRef{std::move(vm)};
|
|
}
|
|
|
|
std::scoped_lock dependents_lock(gVMDependentsMutex);
|
|
|
|
gVMData.reset();
|
|
gVMServiceProtocol.reset();
|
|
gVMIsolateNameServer.reset();
|
|
gVM.reset();
|
|
|
|
// If there is no VM in the process. Initialize one, hold the weak reference
|
|
// and pass a strong reference to the caller.
|
|
auto isolate_name_server = std::make_shared<IsolateNameServer>();
|
|
auto vm = DartVM::Create(std::move(settings), //
|
|
std::move(vm_snapshot), //
|
|
std::move(isolate_snapshot), //
|
|
isolate_name_server //
|
|
);
|
|
|
|
if (!vm) {
|
|
FML_LOG(ERROR) << "Could not create Dart VM instance.";
|
|
return {nullptr};
|
|
}
|
|
|
|
gVMData = vm->GetVMData();
|
|
gVMServiceProtocol = vm->GetServiceProtocol();
|
|
gVMIsolateNameServer = isolate_name_server;
|
|
gVM = vm;
|
|
|
|
if (settings.leak_vm) {
|
|
gVMLeak = new std::shared_ptr<DartVM>(vm);
|
|
}
|
|
|
|
return DartVMRef{std::move(vm)};
|
|
}
|
|
|
|
bool DartVMRef::IsInstanceRunning() {
|
|
std::scoped_lock lock(gVMMutex);
|
|
return !gVM.expired();
|
|
}
|
|
|
|
std::shared_ptr<const DartVMData> DartVMRef::GetVMData() {
|
|
std::scoped_lock lock(gVMDependentsMutex);
|
|
return gVMData.lock();
|
|
}
|
|
|
|
std::shared_ptr<ServiceProtocol> DartVMRef::GetServiceProtocol() {
|
|
std::scoped_lock lock(gVMDependentsMutex);
|
|
return gVMServiceProtocol.lock();
|
|
}
|
|
|
|
std::shared_ptr<IsolateNameServer> DartVMRef::GetIsolateNameServer() {
|
|
std::scoped_lock lock(gVMDependentsMutex);
|
|
return gVMIsolateNameServer.lock();
|
|
}
|
|
|
|
DartVM* DartVMRef::GetRunningVM() {
|
|
std::scoped_lock lock(gVMMutex);
|
|
auto vm = gVM.lock().get();
|
|
FML_CHECK(vm) << "Caller assumed VM would be running when it wasn't";
|
|
return vm;
|
|
}
|
|
|
|
} // namespace flutter
|