mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
`FlutterEnginePostCallbackOnAllNativeThreads` schedule a callback to be run on all engine managed threads. The engine will attempt to service this callback the next time the message loops for each managed thread is idle. Since the engine manages the entire lifecycle of multiple threads, there is no opportunity for the embedders to finely tune the priorities of threads directly, or, perform other thread specific configuration (for example, setting thread names for tracing). This callback gives embedders a chance to affect such tuning. Fixes flutter/flutter#49551 Fixes b/143774406 Fixes b/148278215 Fixes b/148278931
189 lines
8.8 KiB
C++
189 lines
8.8 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.
|
|
|
|
#ifndef FLUTTER_RUNTIME_DART_VM_H_
|
|
#define FLUTTER_RUNTIME_DART_VM_H_
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "flutter/common/settings.h"
|
|
#include "flutter/fml/build_config.h"
|
|
#include "flutter/fml/closure.h"
|
|
#include "flutter/fml/macros.h"
|
|
#include "flutter/fml/memory/ref_counted.h"
|
|
#include "flutter/fml/memory/ref_ptr.h"
|
|
#include "flutter/fml/memory/weak_ptr.h"
|
|
#include "flutter/fml/message_loop.h"
|
|
#include "flutter/lib/ui/isolate_name_server/isolate_name_server.h"
|
|
#include "flutter/runtime/dart_isolate.h"
|
|
#include "flutter/runtime/dart_snapshot.h"
|
|
#include "flutter/runtime/dart_vm_data.h"
|
|
#include "flutter/runtime/service_protocol.h"
|
|
#include "flutter/runtime/skia_concurrent_executor.h"
|
|
#include "third_party/dart/runtime/include/dart_api.h"
|
|
|
|
namespace flutter {
|
|
|
|
//------------------------------------------------------------------------------
|
|
/// @brief Describes a running instance of the Dart VM. There may only be
|
|
/// one running instance of the Dart VM in the process at any given
|
|
/// time. The Dart VM may be created and destroyed on any thread.
|
|
/// Typically, the first Flutter shell instance running in the
|
|
/// process bootstraps the Dart VM in the process as it starts up.
|
|
/// This cost is borne on the platform task runner of that first
|
|
/// Flutter shell. When the last Flutter shell instance is
|
|
/// destroyed, the VM is destroyed as well if all shell instances
|
|
/// were launched with the `Settings::leak_vm` flag set to false. If
|
|
/// there is any shell launch in the process with `leak_vm` set to
|
|
/// true, the VM is never shut down in the process. When the VM is
|
|
/// shutdown, the cost of the shutdown is borne on the platform task
|
|
/// runner of the last shell instance to be shut down.
|
|
///
|
|
/// Due to threading considerations, callers may never create an
|
|
/// instance of the DartVM directly. All constructors to the DartVM
|
|
/// are private. Instead, all callers that need a running VM
|
|
/// reference need to access it via the `DartVMRef::Create` call.
|
|
/// This call returns a strong reference to the running VM if one
|
|
/// exists in the process already. If a running VM instance is not
|
|
/// available in the process, a new instance is created and a strong
|
|
/// reference returned to the callers. The DartVMRef::Create call
|
|
/// ensures that there are no data races during the creation or
|
|
/// shutdown of a Dart VM (since a VM may be created and destroyed
|
|
/// on any thread). Due to this behavior, all callers needing a
|
|
/// running VM instance must provide snapshots and VM settings
|
|
/// necessary to create a VM (even if they end up not being used).
|
|
///
|
|
/// In a running VM instance, the service isolate is launched by
|
|
/// default if the VM is configured to do so. All root isolates must
|
|
/// be launched and referenced explicitly.
|
|
class DartVM {
|
|
public:
|
|
~DartVM();
|
|
|
|
//----------------------------------------------------------------------------
|
|
/// @brief Checks if VM instances in the process can run precompiled
|
|
/// code. This call can be made at any time and does not depend on
|
|
/// a running VM instance. There are no threading restrictions.
|
|
///
|
|
/// @return If VM instances in the process run precompiled code.
|
|
///
|
|
static bool IsRunningPrecompiledCode();
|
|
|
|
//----------------------------------------------------------------------------
|
|
/// @brief The number of times the VM has been launched in the process.
|
|
/// This call is inherently racy because the VM could be in the
|
|
/// process of starting up on another thread between the time the
|
|
/// caller makes this call and uses to result. For this purpose,
|
|
/// this call is only meant to be used as a debugging aid and
|
|
/// primarily only used in tests where the threading model is
|
|
/// consistent.
|
|
///
|
|
/// @return The number of times the VM has been launched.
|
|
///
|
|
static size_t GetVMLaunchCount();
|
|
|
|
//----------------------------------------------------------------------------
|
|
/// @brief The settings used to launch the running VM instance.
|
|
///
|
|
/// @attention Even though all callers that need to acquire a strong
|
|
/// reference to a VM need to provide a valid settings object, the
|
|
/// VM will only reference the settings used by the first caller
|
|
/// that bootstraps the VM in the process.
|
|
///
|
|
/// @return A valid setting object.
|
|
///
|
|
const Settings& GetSettings() const;
|
|
|
|
//----------------------------------------------------------------------------
|
|
/// @brief The VM and isolate snapshots used by this running Dart VM
|
|
/// instance.
|
|
///
|
|
/// @return A valid VM data instance.
|
|
///
|
|
std::shared_ptr<const DartVMData> GetVMData() const;
|
|
|
|
//----------------------------------------------------------------------------
|
|
/// @brief The service protocol instance associated with this running
|
|
/// Dart VM instance. This object manages native handlers for
|
|
/// engine vended service protocol methods.
|
|
///
|
|
/// @return The service protocol for this Dart VM instance.
|
|
///
|
|
std::shared_ptr<ServiceProtocol> GetServiceProtocol() const;
|
|
|
|
//----------------------------------------------------------------------------
|
|
/// @brief The isolate name server for this running VM instance. The
|
|
/// isolate name server maps names (strings) to Dart ports.
|
|
/// Running isolates can discover and communicate with each other
|
|
/// by advertising and resolving ports at well known names.
|
|
///
|
|
/// @return The isolate name server.
|
|
///
|
|
std::shared_ptr<IsolateNameServer> GetIsolateNameServer() const;
|
|
|
|
//----------------------------------------------------------------------------
|
|
/// @brief The task runner whose tasks may be executed concurrently on a
|
|
/// pool of worker threads. All subsystems within a running shell
|
|
/// instance use this worker pool for their concurrent tasks. This
|
|
/// also means that the concurrent worker pool may service tasks
|
|
/// from multiple shell instances. The number of workers in a
|
|
/// concurrent worker pool depends on the hardware concurrency
|
|
/// of the target device (usually equal to the number of logical
|
|
/// CPU cores).
|
|
///
|
|
///
|
|
/// @attention Even though concurrent task queue is associated with a running
|
|
/// Dart VM instance, the worker pool used by the Flutter engine
|
|
/// is NOT shared with the Dart VM internal worker pool. The
|
|
/// presence of this worker pool as member of the Dart VM is
|
|
/// merely to utilize the strong thread safety guarantees around
|
|
/// Dart VM lifecycle for the lifecycle of the concurrent worker
|
|
/// pool as well.
|
|
///
|
|
/// @return The task runner for the concurrent worker thread pool.
|
|
///
|
|
std::shared_ptr<fml::ConcurrentTaskRunner> GetConcurrentWorkerTaskRunner()
|
|
const;
|
|
|
|
//----------------------------------------------------------------------------
|
|
/// @brief The concurrent message loop hosts threads that are used by the
|
|
/// engine to perform tasks long running background tasks.
|
|
/// Typically, to post tasks to this message loop, the
|
|
/// `GetConcurrentWorkerTaskRunner` method may be used.
|
|
///
|
|
/// @see GetConcurrentWorkerTaskRunner
|
|
///
|
|
/// @return The concurrent message loop used by this running Dart VM
|
|
/// instance.
|
|
///
|
|
std::shared_ptr<fml::ConcurrentMessageLoop> GetConcurrentMessageLoop();
|
|
|
|
private:
|
|
const Settings settings_;
|
|
std::shared_ptr<fml::ConcurrentMessageLoop> concurrent_message_loop_;
|
|
SkiaConcurrentExecutor skia_concurrent_executor_;
|
|
std::shared_ptr<const DartVMData> vm_data_;
|
|
const std::shared_ptr<IsolateNameServer> isolate_name_server_;
|
|
const std::shared_ptr<ServiceProtocol> service_protocol_;
|
|
|
|
friend class DartVMRef;
|
|
friend class DartIsolate;
|
|
|
|
static std::shared_ptr<DartVM> Create(
|
|
Settings settings,
|
|
fml::RefPtr<DartSnapshot> vm_snapshot,
|
|
fml::RefPtr<DartSnapshot> isolate_snapshot,
|
|
std::shared_ptr<IsolateNameServer> isolate_name_server);
|
|
|
|
DartVM(std::shared_ptr<const DartVMData> data,
|
|
std::shared_ptr<IsolateNameServer> isolate_name_server);
|
|
|
|
FML_DISALLOW_COPY_AND_ASSIGN(DartVM);
|
|
};
|
|
|
|
} // namespace flutter
|
|
|
|
#endif // FLUTTER_RUNTIME_DART_VM_H_
|