未验证 提交 b7d4278b 编写于 作者: J Jason Simmons 提交者: GitHub

Create separate objects for isolate state and isolate group state (#14268)

Isolate data may need to be deleted on the same thread where it was allocated.
In particular, the task observer set up in the UIDartState ctor must be removed
from the same message loop where it was added.

The engine had been using the same DartIsolate object as the root isolate data
and as the isolate group data.  This object would be deleted when the isolate
group was shut down.  However, group shutdown may occur on a thread associated
with a secondary isolate.  When this happens, cleanup of any state tied to the
root isolate's thread will fail.

This change adds a DartIsolateGroupData object holding state that is common
among all isolates in a group.  DartIsolateGroupData can be deleted on any
thread.

See https://github.com/flutter/flutter/issues/45578
上级 721fb5bc
...@@ -491,6 +491,8 @@ FILE: ../../../flutter/lib/web_ui/lib/ui.dart ...@@ -491,6 +491,8 @@ FILE: ../../../flutter/lib/web_ui/lib/ui.dart
FILE: ../../../flutter/lib/web_ui/tool/unicode_sync_script.dart FILE: ../../../flutter/lib/web_ui/tool/unicode_sync_script.dart
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_group_data.cc
FILE: ../../../flutter/runtime/dart_isolate_group_data.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_lifecycle_unittests.cc
FILE: ../../../flutter/runtime/dart_service_isolate.cc FILE: ../../../flutter/runtime/dart_service_isolate.cc
......
...@@ -46,6 +46,8 @@ source_set("runtime") { ...@@ -46,6 +46,8 @@ source_set("runtime") {
sources = [ sources = [
"dart_isolate.cc", "dart_isolate.cc",
"dart_isolate.h", "dart_isolate.h",
"dart_isolate_group_data.cc",
"dart_isolate_group_data.h",
"dart_service_isolate.cc", "dart_service_isolate.cc",
"dart_service_isolate.h", "dart_service_isolate.h",
"dart_snapshot.cc", "dart_snapshot.cc",
......
此差异已折叠。
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
namespace flutter { namespace flutter {
class DartVM; class DartVM;
class DartIsolateGroupData;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/// @brief Represents an instance of a live isolate. An isolate is a /// @brief Represents an instance of a live isolate. An isolate is a
...@@ -205,13 +206,6 @@ class DartIsolate : public UIDartState { ...@@ -205,13 +206,6 @@ class DartIsolate : public UIDartState {
// |UIDartState| // |UIDartState|
~DartIsolate() override; ~DartIsolate() override;
//----------------------------------------------------------------------------
/// @brief Get the settings used to create this isolate instance.
///
/// @return The settings used in the `CreateRootIsolate` call.
///
const Settings& GetSettings() const;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/// @brief The current phase of the isolate. The engine represents all /// @brief The current phase of the isolate. The engine represents all
/// dart isolates as being in one of the known phases. By invoking /// dart isolates as being in one of the known phases. By invoking
...@@ -376,14 +370,6 @@ class DartIsolate : public UIDartState { ...@@ -376,14 +370,6 @@ class DartIsolate : public UIDartState {
/// ///
void AddIsolateShutdownCallback(const fml::closure& closure); void AddIsolateShutdownCallback(const fml::closure& closure);
//----------------------------------------------------------------------------
/// @brief The snapshot used to launch this isolate. This is referenced
/// by any child isolates launched by the root isolate.
///
/// @return The isolate snapshot.
///
fml::RefPtr<const DartSnapshot> GetIsolateSnapshot() const;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/// @brief A weak pointer to the Dart isolate instance. This instance may /// @brief A weak pointer to the Dart isolate instance. This instance may
/// only be used on the task runner that created the root isolate. /// only be used on the task runner that created the root isolate.
...@@ -403,14 +389,8 @@ class DartIsolate : public UIDartState { ...@@ -403,14 +389,8 @@ class DartIsolate : public UIDartState {
// Root isolate of the VM application // Root isolate of the VM application
bool IsRootIsolate() const { return is_root_isolate_; } bool IsRootIsolate() const { return is_root_isolate_; }
// Isolate that owns IsolateGroup it lives in.
// When --no-enable-isolate-groups dart vm flag is set,
// all child isolates will have their own IsolateGroups.
bool IsGroupRootIsolate() const { return is_group_root_isolate_; }
private: private:
using ChildIsolatePreparer = std::function<bool(DartIsolate*)>;
class AutoFireClosure { class AutoFireClosure {
public: public:
AutoFireClosure(const fml::closure& closure); AutoFireClosure(const fml::closure& closure);
...@@ -424,19 +404,12 @@ class DartIsolate : public UIDartState { ...@@ -424,19 +404,12 @@ class DartIsolate : public UIDartState {
friend class DartVM; friend class DartVM;
Phase phase_ = Phase::Unknown; Phase phase_ = Phase::Unknown;
const Settings settings_;
const fml::RefPtr<const DartSnapshot> isolate_snapshot_;
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;
fml::RefPtr<fml::TaskRunner> message_handling_task_runner_; fml::RefPtr<fml::TaskRunner> message_handling_task_runner_;
const fml::closure isolate_create_callback_;
const fml::closure isolate_shutdown_callback_;
const bool is_root_isolate_; const bool is_root_isolate_;
const bool is_group_root_isolate_;
DartIsolate(const Settings& settings, DartIsolate(const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
TaskRunners task_runners, TaskRunners task_runners,
fml::WeakPtr<SnapshotDelegate> snapshot_delegate, fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
fml::WeakPtr<IOManager> io_manager, fml::WeakPtr<IOManager> io_manager,
...@@ -444,11 +417,7 @@ class DartIsolate : public UIDartState { ...@@ -444,11 +417,7 @@ class DartIsolate : public UIDartState {
fml::WeakPtr<ImageDecoder> image_decoder, fml::WeakPtr<ImageDecoder> image_decoder,
std::string advisory_script_uri, std::string advisory_script_uri,
std::string advisory_script_entrypoint, std::string advisory_script_entrypoint,
const ChildIsolatePreparer& child_isolate_preparer, bool is_root_isolate);
const fml::closure& isolate_create_callback,
const fml::closure& isolate_shutdown_callback,
bool is_root_isolate,
bool is_group_root_isolate);
FML_WARN_UNUSED_RESULT bool Initialize(Dart_Isolate isolate); FML_WARN_UNUSED_RESULT bool Initialize(Dart_Isolate isolate);
void SetMessageHandlingTaskRunner(fml::RefPtr<fml::TaskRunner> runner); void SetMessageHandlingTaskRunner(fml::RefPtr<fml::TaskRunner> runner);
...@@ -465,6 +434,8 @@ class DartIsolate : public UIDartState { ...@@ -465,6 +434,8 @@ class DartIsolate : public UIDartState {
void OnShutdownCallback(); void OnShutdownCallback();
DartIsolateGroupData& GetIsolateGroupData();
// |Dart_IsolateGroupCreateCallback| // |Dart_IsolateGroupCreateCallback|
static Dart_Isolate DartIsolateGroupCreateCallback( static Dart_Isolate DartIsolateGroupCreateCallback(
const char* advisory_script_uri, const char* advisory_script_uri,
...@@ -472,7 +443,7 @@ class DartIsolate : public UIDartState { ...@@ -472,7 +443,7 @@ class DartIsolate : public UIDartState {
const char* package_root, const char* package_root,
const char* package_config, const char* package_config,
Dart_IsolateFlags* flags, Dart_IsolateFlags* flags,
std::shared_ptr<DartIsolate>* embedder_isolate, std::shared_ptr<DartIsolate>* parent_isolate_group,
char** error); char** error);
// |Dart_IsolateInitializeCallback| // |Dart_IsolateInitializeCallback|
...@@ -485,16 +456,10 @@ class DartIsolate : public UIDartState { ...@@ -485,16 +456,10 @@ class DartIsolate : public UIDartState {
Dart_IsolateFlags* flags, Dart_IsolateFlags* flags,
char** error); char** error);
static std::pair<Dart_Isolate /* vm */, static Dart_Isolate CreateDartIsolateGroup(
std::weak_ptr<DartIsolate> /* embedder */> std::unique_ptr<std::shared_ptr<DartIsolateGroupData>> isolate_group_data,
CreateDartVMAndEmbedderObjectPair( std::unique_ptr<std::shared_ptr<DartIsolate>> isolate_data,
const char* advisory_script_uri,
const char* advisory_script_entrypoint,
const char* package_root,
const char* package_config,
Dart_IsolateFlags* flags, Dart_IsolateFlags* flags,
std::shared_ptr<DartIsolate>* parent_embedder_isolate,
bool is_root_isolate,
char** error); char** error);
static bool InitializeIsolate(std::shared_ptr<DartIsolate> embedder_isolate, static bool InitializeIsolate(std::shared_ptr<DartIsolate> embedder_isolate,
...@@ -503,17 +468,17 @@ class DartIsolate : public UIDartState { ...@@ -503,17 +468,17 @@ class DartIsolate : public UIDartState {
// |Dart_IsolateShutdownCallback| // |Dart_IsolateShutdownCallback|
static void DartIsolateShutdownCallback( static void DartIsolateShutdownCallback(
std::shared_ptr<DartIsolate>* isolate_group_data, std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
std::shared_ptr<DartIsolate>* isolate_data); std::shared_ptr<DartIsolate>* isolate_data);
// |Dart_IsolateCleanupCallback| // |Dart_IsolateCleanupCallback|
static void DartIsolateCleanupCallback( static void DartIsolateCleanupCallback(
std::shared_ptr<DartIsolate>* isolate_group_data, std::shared_ptr<DartIsolateGroupData>* isolate_group_data,
std::shared_ptr<DartIsolate>* isolate_data); std::shared_ptr<DartIsolate>* isolate_data);
// |Dart_IsolateGroupCleanupCallback| // |Dart_IsolateGroupCleanupCallback|
static void DartIsolateGroupCleanupCallback( static void DartIsolateGroupCleanupCallback(
std::shared_ptr<DartIsolate>* isolate_group_data); std::shared_ptr<DartIsolateGroupData>* isolate_group_data);
FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate); FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate);
}; };
......
// 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_isolate_group_data.h"
#include "flutter/runtime/dart_snapshot.h"
namespace flutter {
DartIsolateGroupData::DartIsolateGroupData(
const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
const ChildIsolatePreparer& child_isolate_preparer,
const fml::closure& isolate_create_callback,
const fml::closure& isolate_shutdown_callback)
: settings_(settings),
isolate_snapshot_(isolate_snapshot),
advisory_script_uri_(advisory_script_uri),
advisory_script_entrypoint_(advisory_script_entrypoint),
child_isolate_preparer_(child_isolate_preparer),
isolate_create_callback_(isolate_create_callback),
isolate_shutdown_callback_(isolate_shutdown_callback) {
FML_DCHECK(isolate_snapshot_) << "Must contain a valid isolate snapshot.";
}
DartIsolateGroupData::~DartIsolateGroupData() = default;
const Settings& DartIsolateGroupData::GetSettings() const {
return settings_;
}
fml::RefPtr<const DartSnapshot> DartIsolateGroupData::GetIsolateSnapshot()
const {
return isolate_snapshot_;
}
const std::string& DartIsolateGroupData::GetAdvisoryScriptURI() const {
return advisory_script_uri_;
}
const std::string& DartIsolateGroupData::GetAdvisoryScriptEntrypoint() const {
return advisory_script_entrypoint_;
}
const ChildIsolatePreparer& DartIsolateGroupData::GetChildIsolatePreparer()
const {
return child_isolate_preparer_;
}
const fml::closure& DartIsolateGroupData::GetIsolateCreateCallback() const {
return isolate_create_callback_;
}
const fml::closure& DartIsolateGroupData::GetIsolateShutdownCallback() const {
return isolate_shutdown_callback_;
}
void DartIsolateGroupData::SetChildIsolatePreparer(
const ChildIsolatePreparer& value) {
child_isolate_preparer_ = value;
}
} // namespace flutter
// 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_ISOLATE_GROUP_DATA_H_
#define FLUTTER_RUNTIME_DART_ISOLATE_GROUP_DATA_H_
#include <string>
#include "flutter/common/settings.h"
#include "flutter/fml/closure.h"
#include "flutter/fml/memory/ref_ptr.h"
namespace flutter {
class DartIsolate;
class DartSnapshot;
using ChildIsolatePreparer = std::function<bool(DartIsolate*)>;
// Object holding state associated with a Dart isolate group. An instance of
// this class will be provided to Dart_CreateIsolateGroup as the
// isolate_group_data.
//
// This object must be thread safe because the Dart VM can invoke the isolate
// group cleanup callback on any thread.
class DartIsolateGroupData {
public:
DartIsolateGroupData(const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
std::string advisory_script_uri,
std::string advisory_script_entrypoint,
const ChildIsolatePreparer& child_isolate_preparer,
const fml::closure& isolate_create_callback,
const fml::closure& isolate_shutdown_callback);
~DartIsolateGroupData();
const Settings& GetSettings() const;
fml::RefPtr<const DartSnapshot> GetIsolateSnapshot() const;
const std::string& GetAdvisoryScriptURI() const;
const std::string& GetAdvisoryScriptEntrypoint() const;
const ChildIsolatePreparer& GetChildIsolatePreparer() const;
const fml::closure& GetIsolateCreateCallback() const;
const fml::closure& GetIsolateShutdownCallback() const;
void SetChildIsolatePreparer(const ChildIsolatePreparer& value);
private:
FML_DISALLOW_COPY_AND_ASSIGN(DartIsolateGroupData);
const Settings settings_;
const fml::RefPtr<const DartSnapshot> isolate_snapshot_;
const std::string advisory_script_uri_;
const std::string advisory_script_entrypoint_;
ChildIsolatePreparer child_isolate_preparer_;
const fml::closure isolate_create_callback_;
const fml::closure isolate_shutdown_callback_;
};
} // namespace flutter
#endif // FLUTTER_RUNTIME_DART_ISOLATE_GROUP_DATA_H_
...@@ -109,14 +109,15 @@ class AutoIsolateShutdown { ...@@ -109,14 +109,15 @@ class AutoIsolateShutdown {
return; return;
} }
fml::AutoResetWaitableEvent latch; fml::AutoResetWaitableEvent latch;
fml::TaskRunner::RunNowOrPostTask(runner_, [isolate = isolate_, &latch]() { fml::TaskRunner::RunNowOrPostTask(
FML_LOG(INFO) << "Shutting down isolate."; runner_, [isolate = std::move(isolate_), &latch]() {
if (!isolate->Shutdown()) { FML_LOG(INFO) << "Shutting down isolate.";
FML_LOG(ERROR) << "Could not shutdown isolate."; if (!isolate->Shutdown()) {
FML_CHECK(false); FML_LOG(ERROR) << "Could not shutdown isolate.";
} FML_CHECK(false);
latch.Signal(); }
}); latch.Signal();
});
latch.Wait(); latch.Wait();
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册