[flutter_runner] Increase thread stack sizes
Change-Id: I9cfb185f5610f90b1ba6f4c492866640ca633679
diff --git a/runtime/flutter_runner/BUILD.gn b/runtime/flutter_runner/BUILD.gn
index 7db8736..ea54651 100644
--- a/runtime/flutter_runner/BUILD.gn
+++ b/runtime/flutter_runner/BUILD.gn
@@ -98,6 +98,8 @@
"task_observers.h",
"task_runner_adapter.cc",
"task_runner_adapter.h",
+ "thread.cc",
+ "thread.h",
"unique_fdio_ns.h",
"vsync_recorder.cc",
"vsync_recorder.h",
diff --git a/runtime/flutter_runner/engine.cc b/runtime/flutter_runner/engine.cc
index b7a27a3..fb3cde2 100644
--- a/runtime/flutter_runner/engine.cc
+++ b/runtime/flutter_runner/engine.cc
@@ -17,9 +17,9 @@
#include "topaz/runtime/dart/utils/files.h"
#include "fuchsia_font_manager.h"
-#include "loop.h"
#include "platform_view.h"
#include "task_runner_adapter.h"
+#include "thread.h"
namespace flutter_runner {
@@ -58,9 +58,8 @@
// Launch the threads that will be used to run the shell. These threads will
// be joined in the destructor.
- for (auto& loop : host_loops_) {
- loop.reset(MakeObservableLoop(false));
- loop->StartThread();
+ for (auto& thread : threads_) {
+ thread.reset(new Thread());
}
// Set up the session connection.
@@ -183,9 +182,9 @@
const flutter::TaskRunners task_runners(
thread_label_, // Dart thread labels
CreateFMLTaskRunner(async_get_default_dispatcher()), // platform
- CreateFMLTaskRunner(host_loops_[0]->dispatcher()), // gpu
- CreateFMLTaskRunner(host_loops_[1]->dispatcher()), // ui
- CreateFMLTaskRunner(host_loops_[2]->dispatcher()) // io
+ CreateFMLTaskRunner(threads_[0]->dispatcher()), // gpu
+ CreateFMLTaskRunner(threads_[1]->dispatcher()), // ui
+ CreateFMLTaskRunner(threads_[2]->dispatcher()) // io
);
UpdateNativeThreadLabelNames(thread_label_, task_runners);
@@ -294,11 +293,11 @@
Engine::~Engine() {
shell_.reset();
- for (const auto& loop : host_loops_) {
- loop->Quit();
+ for (const auto& thread : threads_) {
+ thread->Quit();
}
- for (const auto& loop : host_loops_) {
- loop->JoinThreads();
+ for (const auto& thread : threads_) {
+ thread->Join();
}
}
diff --git a/runtime/flutter_runner/engine.h b/runtime/flutter_runner/engine.h
index 0996401..b6cdc7f 100644
--- a/runtime/flutter_runner/engine.h
+++ b/runtime/flutter_runner/engine.h
@@ -15,6 +15,7 @@
#include "flutter/fml/macros.h"
#include "flutter/shell/common/shell.h"
#include "isolate_configurator.h"
+#include "thread.h"
namespace flutter_runner {
@@ -47,7 +48,7 @@
Delegate& delegate_;
const std::string thread_label_;
flutter::Settings settings_;
- std::array<std::unique_ptr<async::Loop>, 3> host_loops_;
+ std::array<std::unique_ptr<Thread>, 3> threads_;
std::unique_ptr<IsolateConfigurator> isolate_configurator_;
std::unique_ptr<flutter::Shell> shell_;
zx::event vsync_event_;
diff --git a/runtime/flutter_runner/thread.cc b/runtime/flutter_runner/thread.cc
new file mode 100644
index 0000000..b3a88b9
--- /dev/null
+++ b/runtime/flutter_runner/thread.cc
@@ -0,0 +1,103 @@
+// Copyright 2017 The Chromium 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 <limits.h>
+#include <unistd.h>
+
+#include <algorithm>
+
+#include <lib/async-loop/cpp/loop.h>
+
+#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
diff --git a/runtime/flutter_runner/thread.h b/runtime/flutter_runner/thread.h
new file mode 100644
index 0000000..c347102
--- /dev/null
+++ b/runtime/flutter_runner/thread.h
@@ -0,0 +1,44 @@
+// Copyright 2017 The Chromium 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 TOPAZ_RUNTIME_FLUTTER_RUNNER_THREAD_H_
+#define TOPAZ_RUNTIME_FLUTTER_RUNNER_THREAD_H_
+
+#include <pthread.h>
+
+#include <functional>
+
+#include <lib/async-loop/cpp/loop.h>
+
+#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 // TOPAZ_RUNTIME_FLUTTER_RUNNER_THREAD_H_