mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Replace flutter_runner::Thread with fml::Thread. (flutter/engine#26193)
This commit is contained in:
parent
5bf41ddae1
commit
84d62201b6
@ -229,6 +229,8 @@ FILE: ../../../flutter/fml/platform/darwin/string_range_sanitization_unittests.m
|
||||
FILE: ../../../flutter/fml/platform/fuchsia/message_loop_fuchsia.cc
|
||||
FILE: ../../../flutter/fml/platform/fuchsia/message_loop_fuchsia.h
|
||||
FILE: ../../../flutter/fml/platform/fuchsia/paths_fuchsia.cc
|
||||
FILE: ../../../flutter/fml/platform/fuchsia/task_observers.cc
|
||||
FILE: ../../../flutter/fml/platform/fuchsia/task_observers.h
|
||||
FILE: ../../../flutter/fml/platform/linux/message_loop_linux.cc
|
||||
FILE: ../../../flutter/fml/platform/linux/message_loop_linux.h
|
||||
FILE: ../../../flutter/fml/platform/linux/paths_linux.cc
|
||||
@ -1360,8 +1362,6 @@ FILE: ../../../flutter/shell/platform/fuchsia/flutter/keyboard.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/keyboard.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/keyboard_unittest.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/logging.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/loop.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/loop.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/main.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/aot_product_runtime
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/meta/aot_runtime
|
||||
@ -1383,12 +1383,8 @@ FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner_tzdata_unittest.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/runner_unittest.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/surface.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/surface.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_observers.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_observers.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_runner_adapter.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/task_runner_adapter.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/thread.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/thread.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/unique_fdio_ns.h
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/vsync_waiter.cc
|
||||
FILE: ../../../flutter/shell/platform/fuchsia/flutter/vsync_waiter.h
|
||||
|
||||
@ -180,6 +180,8 @@ source_set("fml") {
|
||||
"platform/fuchsia/message_loop_fuchsia.cc",
|
||||
"platform/fuchsia/message_loop_fuchsia.h",
|
||||
"platform/fuchsia/paths_fuchsia.cc",
|
||||
"platform/fuchsia/task_observers.cc",
|
||||
"platform/fuchsia/task_observers.h",
|
||||
]
|
||||
|
||||
public_deps += [
|
||||
|
||||
@ -8,11 +8,25 @@
|
||||
#include <lib/async/cpp/task.h>
|
||||
#include <lib/async/default.h>
|
||||
#include <lib/zx/time.h>
|
||||
#include "flutter/fml/platform/fuchsia/task_observers.h"
|
||||
|
||||
namespace fml {
|
||||
|
||||
MessageLoopFuchsia::MessageLoopFuchsia()
|
||||
: loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {
|
||||
namespace {
|
||||
|
||||
// See comment on `ExecuteAfterTaskObservers` for explanation.
|
||||
static void LoopEpilogue(async_loop_t*, void*) {
|
||||
ExecuteAfterTaskObservers();
|
||||
}
|
||||
|
||||
constexpr async_loop_config_t kLoopConfig = {
|
||||
.make_default_for_current_thread = false,
|
||||
.epilogue = &LoopEpilogue,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
MessageLoopFuchsia::MessageLoopFuchsia() : loop_(&kLoopConfig) {
|
||||
async_set_default_dispatcher(loop_.dispatcher());
|
||||
}
|
||||
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "task_observers.h"
|
||||
#include "flutter/fml/platform/fuchsia/task_observers.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace flutter_runner {
|
||||
namespace fml {
|
||||
|
||||
thread_local std::map<intptr_t, fit::closure> tTaskObservers;
|
||||
|
||||
@ -27,4 +27,4 @@ void CurrentMessageLoopRemoveAfterTaskObserver(intptr_t key) {
|
||||
tTaskObservers.erase(key);
|
||||
}
|
||||
|
||||
} // namespace flutter_runner
|
||||
} // namespace fml
|
||||
40
engine/src/flutter/fml/platform/fuchsia/task_observers.h
Normal file
40
engine/src/flutter/fml/platform/fuchsia/task_observers.h
Normal file
@ -0,0 +1,40 @@
|
||||
// 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_SHELL_PLATFORM_FUCHSIA_TASK_OBSERVERS_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_TASK_OBSERVERS_H_
|
||||
|
||||
#include <lib/fit/function.h>
|
||||
|
||||
namespace fml {
|
||||
|
||||
// Executes all closures that were registered via
|
||||
// `CurrentMessageLoopAddAfterTaskObserver` on this thread.
|
||||
//
|
||||
// WARNING(fxbug.dev/77957): These task observers are distinct from the task
|
||||
// observers that can be specified via `fml::MessageLoop::AddTaskObserver` and
|
||||
// they behave differently!
|
||||
//
|
||||
// Task observers registered via `fml::MessageLoop::AddTaskObserver` only fire
|
||||
// after work that was posted via the `fml::MessageLoop`'s `TaskRunner`
|
||||
// completes. Work that is posted directly to the Fuchsia message loop (e.g.
|
||||
// using `async::PostTask(async_get_default_dispatcher(), ...)`) is invisible to
|
||||
// `fml::MessageLoop`, so the `fml::MessageLoop`'s task observers don't fire.
|
||||
//
|
||||
// The task observers registered with `CurrentMessageLoopAddAfterTaskObserver`,
|
||||
// however, fire after _every_ work item is completed, regardless of whether it
|
||||
// was posted to the Fuchsia message loop directly or via `fml::MessageLoop`.
|
||||
//
|
||||
// These two mechanisms are redundant and confusing, so we should fix it
|
||||
// somehow.
|
||||
void ExecuteAfterTaskObservers();
|
||||
|
||||
void CurrentMessageLoopAddAfterTaskObserver(intptr_t key,
|
||||
fit::closure observer);
|
||||
|
||||
void CurrentMessageLoopRemoveAfterTaskObserver(intptr_t key);
|
||||
|
||||
} // namespace fml
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_TASK_OBSERVERS_H_
|
||||
@ -68,20 +68,14 @@ template("runner_sources") {
|
||||
"keyboard.cc",
|
||||
"keyboard.h",
|
||||
"logging.h",
|
||||
"loop.cc",
|
||||
"loop.h",
|
||||
"platform_view.cc",
|
||||
"platform_view.h",
|
||||
"runner.cc",
|
||||
"runner.h",
|
||||
"surface.cc",
|
||||
"surface.h",
|
||||
"task_observers.cc",
|
||||
"task_observers.h",
|
||||
"task_runner_adapter.cc",
|
||||
"task_runner_adapter.h",
|
||||
"thread.cc",
|
||||
"thread.h",
|
||||
"unique_fdio_ns.h",
|
||||
"vsync_waiter.cc",
|
||||
"vsync_waiter.h",
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#define FML_USED_ON_EMBEDDER
|
||||
|
||||
#include "component.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
@ -27,6 +29,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "flutter/fml/mapping.h"
|
||||
#include "flutter/fml/platform/fuchsia/task_observers.h"
|
||||
#include "flutter/fml/synchronization/waitable_event.h"
|
||||
#include "flutter/fml/unique_fd.h"
|
||||
#include "flutter/runtime/dart_vm_lifecycle.h"
|
||||
@ -37,9 +40,6 @@
|
||||
#include "runtime/dart/utils/tempfs.h"
|
||||
#include "runtime/dart/utils/vmo.h"
|
||||
|
||||
#include "task_observers.h"
|
||||
#include "task_runner_adapter.h"
|
||||
|
||||
// TODO(kaushikiska): Use these constants from ::llcpp::fuchsia::io
|
||||
// Can read from target object.
|
||||
constexpr uint32_t OPEN_RIGHT_READABLE = 1u;
|
||||
@ -186,11 +186,11 @@ ActiveApplication Application::Create(
|
||||
fuchsia::sys::StartupInfo startup_info,
|
||||
std::shared_ptr<sys::ServiceDirectory> runner_incoming_services,
|
||||
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
|
||||
std::unique_ptr<Thread> thread = std::make_unique<Thread>();
|
||||
auto thread = std::make_unique<fml::Thread>();
|
||||
std::unique_ptr<Application> application;
|
||||
|
||||
fml::AutoResetWaitableEvent latch;
|
||||
async::PostTask(thread->dispatcher(), [&]() mutable {
|
||||
thread->GetTaskRunner()->PostTask([&]() mutable {
|
||||
application.reset(
|
||||
new Application(std::move(termination_callback), std::move(package),
|
||||
std::move(startup_info), runner_incoming_services,
|
||||
@ -199,7 +199,8 @@ ActiveApplication Application::Create(
|
||||
});
|
||||
|
||||
latch.Wait();
|
||||
return {.thread = std::move(thread), .application = std::move(application)};
|
||||
return {.platform_thread = std::move(thread),
|
||||
.application = std::move(application)};
|
||||
}
|
||||
|
||||
Application::Application(
|
||||
@ -491,11 +492,11 @@ Application::Application(
|
||||
settings_.leak_vm = false;
|
||||
|
||||
settings_.task_observer_add =
|
||||
std::bind(&CurrentMessageLoopAddAfterTaskObserver, std::placeholders::_1,
|
||||
std::placeholders::_2);
|
||||
std::bind(&fml::CurrentMessageLoopAddAfterTaskObserver,
|
||||
std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
settings_.task_observer_remove = std::bind(
|
||||
&CurrentMessageLoopRemoveAfterTaskObserver, std::placeholders::_1);
|
||||
&fml::CurrentMessageLoopRemoveAfterTaskObserver, std::placeholders::_1);
|
||||
|
||||
settings_.log_message_callback = [](const std::string& tag,
|
||||
const std::string& message) {
|
||||
@ -517,8 +518,7 @@ Application::Application(
|
||||
#endif // defined(__aarch64__)
|
||||
|
||||
auto weak_application = weak_factory_.GetWeakPtr();
|
||||
auto platform_task_runner =
|
||||
CreateFMLTaskRunner(async_get_default_dispatcher());
|
||||
auto platform_task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();
|
||||
const std::string component_url = package.resolved_url;
|
||||
settings_.unhandled_exception_callback = [weak_application,
|
||||
platform_task_runner,
|
||||
|
||||
@ -26,7 +26,6 @@
|
||||
|
||||
#include "engine.h"
|
||||
#include "flutter_runner_product_configuration.h"
|
||||
#include "thread.h"
|
||||
#include "unique_fdio_ns.h"
|
||||
|
||||
namespace flutter_runner {
|
||||
@ -34,12 +33,12 @@ namespace flutter_runner {
|
||||
class Application;
|
||||
|
||||
struct ActiveApplication {
|
||||
std::unique_ptr<Thread> thread;
|
||||
std::unique_ptr<fml::Thread> platform_thread;
|
||||
std::unique_ptr<Application> application;
|
||||
|
||||
ActiveApplication& operator=(ActiveApplication&& other) noexcept {
|
||||
if (this != &other) {
|
||||
this->thread.reset(other.thread.release());
|
||||
this->platform_thread.reset(other.platform_thread.release());
|
||||
this->application.reset(other.application.release());
|
||||
}
|
||||
return *this;
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#define FML_USED_ON_EMBEDDER
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
#include <lib/async/cpp/task.h>
|
||||
@ -10,6 +12,7 @@
|
||||
#include "flutter/common/graphics/persistent_cache.h"
|
||||
#include "flutter/common/task_runners.h"
|
||||
#include "flutter/fml/make_copyable.h"
|
||||
#include "flutter/fml/message_loop.h"
|
||||
#include "flutter/fml/synchronization/waitable_event.h"
|
||||
#include "flutter/fml/task_runner.h"
|
||||
#include "flutter/runtime/dart_vm_lifecycle.h"
|
||||
@ -24,7 +27,6 @@
|
||||
#include "fuchsia_intl.h"
|
||||
#include "platform_view.h"
|
||||
#include "surface.h"
|
||||
#include "task_runner_adapter.h"
|
||||
#include "vsync_waiter.h"
|
||||
|
||||
#if defined(LEGACY_FUCHSIA_EMBEDDER)
|
||||
@ -80,12 +82,15 @@ Engine::Engine(Delegate& delegate,
|
||||
|
||||
// Get the task runners from the managed threads. The current thread will be
|
||||
// used as the "platform" thread.
|
||||
fml::RefPtr<fml::TaskRunner> platform_task_runner =
|
||||
fml::MessageLoop::GetCurrent().GetTaskRunner();
|
||||
|
||||
const flutter::TaskRunners task_runners(
|
||||
thread_label_, // Dart thread labels
|
||||
CreateFMLTaskRunner(async_get_default_dispatcher()), // platform
|
||||
CreateFMLTaskRunner(threads_[0].dispatcher()), // raster
|
||||
CreateFMLTaskRunner(threads_[1].dispatcher()), // ui
|
||||
CreateFMLTaskRunner(threads_[2].dispatcher()) // io
|
||||
thread_label_, // Dart thread labels
|
||||
platform_task_runner, // platform
|
||||
threads_[0].GetTaskRunner(), // raster
|
||||
threads_[1].GetTaskRunner(), // ui
|
||||
threads_[2].GetTaskRunner() // io
|
||||
);
|
||||
UpdateNativeThreadLabelNames(thread_label_, task_runners);
|
||||
|
||||
@ -120,10 +125,9 @@ Engine::Engine(Delegate& delegate,
|
||||
// This handles the fidl error callback when the Session connection is
|
||||
// broken. The SessionListener interface also has an OnError method, which is
|
||||
// invoked on the platform thread (in PlatformView).
|
||||
fml::closure session_error_callback = [dispatcher =
|
||||
async_get_default_dispatcher(),
|
||||
fml::closure session_error_callback = [task_runner = platform_task_runner,
|
||||
weak = weak_factory_.GetWeakPtr()]() {
|
||||
async::PostTask(dispatcher, [weak]() {
|
||||
task_runner->PostTask([weak]() {
|
||||
if (weak) {
|
||||
weak->Terminate();
|
||||
}
|
||||
@ -221,9 +225,9 @@ Engine::Engine(Delegate& delegate,
|
||||
// platform thread when that happens. The Session itself should also be
|
||||
// disconnected when this happens, and it will also attempt to terminate.
|
||||
fit::closure on_session_listener_error_callback =
|
||||
[dispatcher = async_get_default_dispatcher(),
|
||||
[task_runner = platform_task_runner,
|
||||
weak = weak_factory_.GetWeakPtr()]() {
|
||||
async::PostTask(dispatcher, [weak]() {
|
||||
task_runner->PostTask([weak]() {
|
||||
if (weak) {
|
||||
weak->Terminate();
|
||||
}
|
||||
@ -511,9 +515,6 @@ Engine::Engine(Delegate& delegate,
|
||||
|
||||
Engine::~Engine() {
|
||||
shell_.reset();
|
||||
for (auto& thread : threads_) {
|
||||
thread.Quit();
|
||||
}
|
||||
for (auto& thread : threads_) {
|
||||
thread.Join();
|
||||
}
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
#include "flutter_runner_product_configuration.h"
|
||||
#include "fuchsia_external_view_embedder.h"
|
||||
#include "isolate_configurator.h"
|
||||
#include "thread.h"
|
||||
#include "vulkan_surface_producer.h"
|
||||
|
||||
#if defined(LEGACY_FUCHSIA_EMBEDDER)
|
||||
@ -73,7 +72,7 @@ class Engine final {
|
||||
Delegate& delegate_;
|
||||
|
||||
const std::string thread_label_;
|
||||
std::array<Thread, 3> threads_;
|
||||
std::array<fml::Thread, 3> threads_;
|
||||
|
||||
std::shared_ptr<DefaultSessionConnection> session_connection_;
|
||||
std::optional<VulkanSurfaceProducer> surface_producer_;
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "loop.h"
|
||||
#include "rapidjson/document.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "rapidjson/writer.h"
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
// 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 "loop.h"
|
||||
|
||||
#include <lib/async-loop/loop.h>
|
||||
#include <lib/async/default.h>
|
||||
|
||||
#include "task_observers.h"
|
||||
|
||||
namespace flutter_runner {
|
||||
|
||||
namespace {
|
||||
|
||||
static void LoopEpilogue(async_loop_t*, void*) {
|
||||
ExecuteAfterTaskObservers();
|
||||
}
|
||||
|
||||
constexpr async_loop_config_t kAttachedLoopConfig = {
|
||||
.default_accessors =
|
||||
{
|
||||
.getter = async_get_default_dispatcher,
|
||||
.setter = async_set_default_dispatcher,
|
||||
},
|
||||
.make_default_for_current_thread = true,
|
||||
.epilogue = &LoopEpilogue,
|
||||
};
|
||||
|
||||
constexpr async_loop_config_t kDetachedLoopConfig = {
|
||||
.default_accessors =
|
||||
{
|
||||
.getter = async_get_default_dispatcher,
|
||||
.setter = async_set_default_dispatcher,
|
||||
},
|
||||
.make_default_for_current_thread = false,
|
||||
.epilogue = &LoopEpilogue,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
async::Loop* MakeObservableLoop(bool attachToThread) {
|
||||
return new async::Loop(
|
||||
&(attachToThread ? kAttachedLoopConfig : kDetachedLoopConfig));
|
||||
}
|
||||
|
||||
} // namespace flutter_runner
|
||||
@ -1,17 +0,0 @@
|
||||
// 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_SHELL_PLATFORM_FUCHSIA_LOOP_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_LOOP_H_
|
||||
|
||||
#include <lib/async-loop/cpp/loop.h>
|
||||
|
||||
namespace flutter_runner {
|
||||
|
||||
// Creates a loop which allows task observers to be attached to it.
|
||||
async::Loop* MakeObservableLoop(bool attachToThread);
|
||||
|
||||
} // namespace flutter_runner
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_LOOP_H_
|
||||
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#define FML_USED_ON_EMBEDDER
|
||||
|
||||
#include <lib/async-loop/cpp/loop.h>
|
||||
#include <lib/sys/inspect/cpp/component.h>
|
||||
#include <lib/trace-provider/provider.h>
|
||||
@ -9,7 +11,8 @@
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "loop.h"
|
||||
#include "fml/message_loop.h"
|
||||
#include "lib/async/default.h"
|
||||
#include "platform/utils.h"
|
||||
#include "runner.h"
|
||||
#include "runtime/dart/utils/build_info.h"
|
||||
@ -17,7 +20,7 @@
|
||||
#include "runtime/dart/utils/tempfs.h"
|
||||
|
||||
int main(int argc, char const* argv[]) {
|
||||
std::unique_ptr<async::Loop> loop(flutter_runner::MakeObservableLoop(true));
|
||||
fml::MessageLoop::EnsureInitializedForCurrentThread();
|
||||
|
||||
// Create our component context which is served later.
|
||||
auto context = sys::ComponentContext::Create();
|
||||
@ -35,7 +38,8 @@ int main(int argc, char const* argv[]) {
|
||||
bool already_started;
|
||||
// Use CreateSynchronously to prevent loss of early events.
|
||||
trace::TraceProviderWithFdio::CreateSynchronously(
|
||||
loop->dispatcher(), "flutter_runner", &provider, &already_started);
|
||||
async_get_default_dispatcher(), "flutter_runner", &provider,
|
||||
&already_started);
|
||||
}
|
||||
|
||||
// Set up the process-wide /tmp memfs.
|
||||
@ -43,12 +47,13 @@ int main(int argc, char const* argv[]) {
|
||||
|
||||
FML_DLOG(INFO) << "Flutter application services initialized.";
|
||||
|
||||
flutter_runner::Runner runner(loop.get(), context.get());
|
||||
fml::MessageLoop& loop = fml::MessageLoop::GetCurrent();
|
||||
flutter_runner::Runner runner(loop.GetTaskRunner(), context.get());
|
||||
|
||||
// Wait to serve until we have finished all of our setup.
|
||||
context->outgoing()->ServeFromStartupInfo();
|
||||
|
||||
loop->Run();
|
||||
loop.Run();
|
||||
FML_DLOG(INFO) << "Flutter application services terminated.";
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "flutter/fml/make_copyable.h"
|
||||
#include "flutter/lib/ui/text/font_collection.h"
|
||||
#include "flutter/runtime/dart_vm.h"
|
||||
#include "lib/async/default.h"
|
||||
#include "lib/sys/cpp/component_context.h"
|
||||
#include "runtime/dart/utils/files.h"
|
||||
#include "runtime/dart/utils/root_inspect_node.h"
|
||||
@ -148,8 +149,9 @@ static void RegisterProfilerSymbols(const char* symbols_path,
|
||||
}
|
||||
#endif // !defined(DART_PRODUCT)
|
||||
|
||||
Runner::Runner(async::Loop* loop, sys::ComponentContext* context)
|
||||
: loop_(loop), context_(context) {
|
||||
Runner::Runner(fml::RefPtr<fml::TaskRunner> task_runner,
|
||||
sys::ComponentContext* context)
|
||||
: task_runner_(task_runner), context_(context) {
|
||||
#if !defined(DART_PRODUCT)
|
||||
// The VM service isolate uses the process-wide namespace. It writes the
|
||||
// vm service protocol port under /tmp. The VMServiceObject exposes that
|
||||
@ -232,12 +234,11 @@ void Runner::StartComponent(
|
||||
// there being multiple application runner instance in the process at the same
|
||||
// time. So it is safe to use the raw pointer.
|
||||
Application::TerminationCallback termination_callback =
|
||||
[task_runner = loop_->dispatcher(), //
|
||||
application_runner = this //
|
||||
](const Application* application) {
|
||||
async::PostTask(task_runner, [application_runner, application]() {
|
||||
application_runner->OnApplicationTerminate(application);
|
||||
});
|
||||
[application_runner = this](const Application* application) {
|
||||
application_runner->task_runner_->PostTask(
|
||||
[application_runner, application]() {
|
||||
application_runner->OnApplicationTerminate(application);
|
||||
});
|
||||
};
|
||||
|
||||
auto active_application = Application::Create(
|
||||
@ -266,21 +267,17 @@ void Runner::OnApplicationTerminate(const Application* application) {
|
||||
// Grab the items out of the entry because we will have to rethread the
|
||||
// destruction.
|
||||
auto application_to_destroy = std::move(active_application.application);
|
||||
auto application_thread = std::move(active_application.thread);
|
||||
auto application_thread = std::move(active_application.platform_thread);
|
||||
|
||||
// Delegate the entry.
|
||||
active_applications_.erase(application);
|
||||
|
||||
// Post the task to destroy the application and quit its message loop.
|
||||
async::PostTask(
|
||||
application_thread->dispatcher(),
|
||||
fml::MakeCopyable([instance = std::move(application_to_destroy),
|
||||
thread = application_thread.get()]() mutable {
|
||||
instance.reset();
|
||||
thread->Quit();
|
||||
}));
|
||||
application_thread->GetTaskRunner()->PostTask(fml::MakeCopyable(
|
||||
[instance = std::move(application_to_destroy),
|
||||
thread = application_thread.get()]() mutable { instance.reset(); }));
|
||||
|
||||
// This works because just posted the quit task on the hosted thread.
|
||||
// Terminate and join the thread's message loop.
|
||||
application_thread->Join();
|
||||
}
|
||||
|
||||
@ -304,27 +301,36 @@ bool Runner::SetupTZDataInternal() {
|
||||
|
||||
#if !defined(DART_PRODUCT)
|
||||
void Runner::SetupTraceObserver() {
|
||||
trace_observer_ = std::make_unique<trace::TraceObserver>();
|
||||
trace_observer_->Start(loop_->dispatcher(), [runner = this]() {
|
||||
if (!trace_is_category_enabled("dart:profiler")) {
|
||||
return;
|
||||
}
|
||||
if (trace_state() == TRACE_STARTED) {
|
||||
runner->prolonged_context_ = trace_acquire_prolonged_context();
|
||||
Dart_StartProfiling();
|
||||
} else if (trace_state() == TRACE_STOPPING) {
|
||||
for (auto& it : runner->active_applications_) {
|
||||
fml::AutoResetWaitableEvent latch;
|
||||
async::PostTask(it.second.thread->dispatcher(), [&]() {
|
||||
it.second.application->WriteProfileToTrace();
|
||||
latch.Signal();
|
||||
});
|
||||
latch.Wait();
|
||||
fml::AutoResetWaitableEvent latch;
|
||||
|
||||
fml::TaskRunner::RunNowOrPostTask(task_runner_, [&]() {
|
||||
// Running this initialization code on task_runner_ ensures that the call to
|
||||
// `async_get_default_dispatcher()` will capture the correct dispatcher.
|
||||
trace_observer_ = std::make_unique<trace::TraceObserver>();
|
||||
trace_observer_->Start(async_get_default_dispatcher(), [runner = this]() {
|
||||
if (!trace_is_category_enabled("dart:profiler")) {
|
||||
return;
|
||||
}
|
||||
Dart_StopProfiling();
|
||||
trace_release_prolonged_context(runner->prolonged_context_);
|
||||
}
|
||||
if (trace_state() == TRACE_STARTED) {
|
||||
runner->prolonged_context_ = trace_acquire_prolonged_context();
|
||||
Dart_StartProfiling();
|
||||
} else if (trace_state() == TRACE_STOPPING) {
|
||||
for (auto& it : runner->active_applications_) {
|
||||
fml::AutoResetWaitableEvent latch;
|
||||
fml::TaskRunner::RunNowOrPostTask(
|
||||
it.second.platform_thread->GetTaskRunner(), [&]() {
|
||||
it.second.application->WriteProfileToTrace();
|
||||
latch.Signal();
|
||||
});
|
||||
latch.Wait();
|
||||
}
|
||||
Dart_StopProfiling();
|
||||
trace_release_prolonged_context(runner->prolonged_context_);
|
||||
}
|
||||
});
|
||||
latch.Signal();
|
||||
});
|
||||
latch.Wait();
|
||||
}
|
||||
#endif // !defined(DART_PRODUCT)
|
||||
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
|
||||
#include "component.h"
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "fml/memory/ref_ptr.h"
|
||||
#include "fml/task_runner.h"
|
||||
#include "lib/fidl/cpp/binding_set.h"
|
||||
#include "runtime/dart/utils/vmservice_object.h"
|
||||
|
||||
@ -25,13 +27,14 @@ namespace flutter_runner {
|
||||
// their own threads.
|
||||
class Runner final : public fuchsia::sys::Runner {
|
||||
public:
|
||||
// Does not take ownership of loop or context.
|
||||
Runner(async::Loop* loop, sys::ComponentContext* context);
|
||||
// Does not take ownership of context.
|
||||
Runner(fml::RefPtr<fml::TaskRunner> task_runner,
|
||||
sys::ComponentContext* context);
|
||||
|
||||
~Runner();
|
||||
|
||||
private:
|
||||
async::Loop* loop_;
|
||||
fml::RefPtr<fml::TaskRunner> task_runner_;
|
||||
|
||||
sys::ComponentContext* context_;
|
||||
fidl::BindingSet<fuchsia::sys::Runner> active_applications_bindings_;
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
// 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_SHELL_PLATFORM_FUCHSIA_TASK_OBSERVERS_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_TASK_OBSERVERS_H_
|
||||
|
||||
#include <lib/fit/function.h>
|
||||
|
||||
namespace flutter_runner {
|
||||
|
||||
void ExecuteAfterTaskObservers();
|
||||
|
||||
void CurrentMessageLoopAddAfterTaskObserver(intptr_t key,
|
||||
fit::closure observer);
|
||||
|
||||
void CurrentMessageLoopRemoveAfterTaskObserver(intptr_t key);
|
||||
|
||||
} // namespace flutter_runner
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_TASK_OBSERVERS_H_
|
||||
@ -1,102 +0,0 @@
|
||||
// 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 "thread.h"
|
||||
|
||||
#include <lib/async-loop/cpp/loop.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
#include "loop.h"
|
||||
|
||||
namespace flutter_runner {
|
||||
|
||||
typedef void (*ThreadEntry)(Thread*);
|
||||
|
||||
namespace {
|
||||
|
||||
size_t NextPageSizeMultiple(size_t size) {
|
||||
const size_t page_size = sysconf(_SC_PAGE_SIZE);
|
||||
FML_CHECK(page_size != 0);
|
||||
|
||||
size = std::max<size_t>(size, page_size);
|
||||
|
||||
size_t rem = size % page_size;
|
||||
|
||||
if (rem == 0) {
|
||||
return size;
|
||||
}
|
||||
|
||||
return size + page_size - rem;
|
||||
}
|
||||
|
||||
bool CreateThread(pthread_t* thread,
|
||||
ThreadEntry main,
|
||||
Thread* argument,
|
||||
size_t stack_size) {
|
||||
pthread_attr_t thread_attributes;
|
||||
|
||||
if (pthread_attr_init(&thread_attributes) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
stack_size = std::max<size_t>(NextPageSizeMultiple(PTHREAD_STACK_MIN),
|
||||
NextPageSizeMultiple(stack_size));
|
||||
|
||||
if (pthread_attr_setstacksize(&thread_attributes, stack_size) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto result =
|
||||
pthread_create(thread, &thread_attributes,
|
||||
reinterpret_cast<void* (*)(void*)>(main), argument);
|
||||
|
||||
pthread_attr_destroy(&thread_attributes);
|
||||
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
Thread::Thread() {
|
||||
loop_.reset(MakeObservableLoop(false));
|
||||
valid_ = CreateThread(
|
||||
&thread_, [](Thread* thread) { thread->Main(); }, this, 1 << 20);
|
||||
}
|
||||
|
||||
Thread::~Thread() {
|
||||
Join();
|
||||
}
|
||||
|
||||
bool Thread::IsValid() const {
|
||||
return valid_;
|
||||
}
|
||||
|
||||
async_dispatcher_t* Thread::dispatcher() const {
|
||||
return loop_->dispatcher();
|
||||
}
|
||||
|
||||
void Thread::Main() {
|
||||
async_set_default_dispatcher(loop_->dispatcher());
|
||||
loop_->Run();
|
||||
}
|
||||
|
||||
void Thread::Quit() {
|
||||
loop_->Quit();
|
||||
}
|
||||
|
||||
bool Thread::Join() {
|
||||
if (!valid_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = pthread_join(thread_, nullptr) == 0;
|
||||
valid_ = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace flutter_runner
|
||||
@ -1,44 +0,0 @@
|
||||
// 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_SHELL_PLATFORM_FUCHSIA_THREAD_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_THREAD_H_
|
||||
|
||||
#include <lib/async-loop/cpp/loop.h>
|
||||
#include <lib/async/default.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
|
||||
namespace flutter_runner {
|
||||
|
||||
class Thread {
|
||||
public:
|
||||
Thread();
|
||||
|
||||
~Thread();
|
||||
|
||||
void Quit();
|
||||
|
||||
bool Join();
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
async_dispatcher_t* dispatcher() const;
|
||||
|
||||
private:
|
||||
bool valid_;
|
||||
pthread_t thread_;
|
||||
std::unique_ptr<async::Loop> loop_;
|
||||
|
||||
void Main();
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(Thread);
|
||||
};
|
||||
|
||||
} // namespace flutter_runner
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_THREAD_H_
|
||||
Loading…
x
Reference in New Issue
Block a user