Skip to content

Commit

Permalink
Use the Starboard message pump. (#4772)
Browse files Browse the repository at this point in the history
The setup is similar to ATV/iOS where the existing platform main thread
is re-used and the UI message pump just attaches to it.

b/392620765
b/391414243
  • Loading branch information
y4vor authored Feb 1, 2025
1 parent 86e2216 commit aa99278
Show file tree
Hide file tree
Showing 34 changed files with 388 additions and 63 deletions.
10 changes: 10 additions & 0 deletions base/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,12 @@ component("base") {
]
}

if (is_starboard) {
sources += [
"message_loop/message_pump_ui_starboard.cc",
"message_loop/message_pump_ui_starboard.h",
]
}
if (is_linux || is_chromeos) {
sources += [
"debug/proc_maps_linux.cc",
Expand Down Expand Up @@ -1067,6 +1073,10 @@ component("base") {
deps += [ "//base/time/buildflags:buildflags" ]
}

if (is_starboard) {
deps += [ "//starboard($starboard_toolchain)" ]
}

if (build_rust_json_reader) {
deps += [ "//third_party/rust/serde_json_lenient/v0_1/wrapper" ]
}
Expand Down
4 changes: 4 additions & 0 deletions base/message_loop/message_pump_for_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include "base/message_loop/message_pump_win.h"
#elif BUILDFLAG(IS_ANDROID)
#include "base/message_loop/message_pump_android.h"
#elif BUILDFLAG(IS_STARBOARD)
#include "base/message_loop/message_pump_ui_starboard.h"
#elif BUILDFLAG(IS_APPLE)
#include "base/message_loop/message_pump.h"
#elif BUILDFLAG(IS_NACL) || BUILDFLAG(IS_AIX)
Expand All @@ -34,6 +36,8 @@ using MessagePumpForUI = MessagePumpForUI;
#elif BUILDFLAG(IS_ANDROID)
// Android defines it as-is.
using MessagePumpForUI = MessagePumpForUI;
#elif BUILDFLAG(IS_STARBOARD)
using MessagePumpForUI = MessagePumpUIStarboard;
#elif BUILDFLAG(IS_APPLE)
// MessagePumpForUI isn't bound to a specific impl on Mac. While each impl can
// be represented by a plain MessagePump: MessagePumpMac::Create() must be used
Expand Down
10 changes: 10 additions & 0 deletions base/message_loop/message_pump_ui_starboard.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "base/message_loop/message_pump_ui_starboard.h"

#include "base/logging.h"
#include "base/notreached.h"
#include "base/time/time.h"
#include "starboard/event.h"
#include "starboard/system.h"
Expand Down Expand Up @@ -107,11 +108,20 @@ void MessagePumpUIStarboard::Attach(Delegate* delegate) {
// return control back to the Looper.

SetDelegate(delegate);

run_loop_ = std::make_unique<RunLoop>();
// Since the RunLoop was just created above, BeforeRun should be guaranteed to
// return true (it only returns false if the RunLoop has been Quit already).
CHECK(run_loop_->BeforeRun());
}

void MessagePumpUIStarboard::Quit() {
delegate_ = nullptr;
CancelAll();
if (run_loop_) {
run_loop_->AfterRun();
run_loop_ = nullptr;
}
}

void MessagePumpUIStarboard::ScheduleWork() {
Expand Down
27 changes: 26 additions & 1 deletion base/message_loop/message_pump_ui_starboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include "base/base_export.h"
#include "base/message_loop/message_pump.h"
#include "base/message_loop/watchable_io_message_pump_posix.h"
#include "base/run_loop.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "starboard/event.h"
Expand All @@ -37,8 +39,28 @@ namespace base {
// Starboard message pump as a MessageLoop. That would typically be for the
// entire lifetime of the application, and in that case, the MessageLoop would
// traditionally be deleted in the kSbEventStop handler.
class BASE_EXPORT MessagePumpUIStarboard : public MessagePump {
class BASE_EXPORT MessagePumpUIStarboard : public MessagePump, public WatchableIOMessagePumpPosix {
public:

// TODO (cobalt b/393772370): Remove the stub FD support when x11/wayland are disabled.
class FdWatchController : public FdWatchControllerInterface {
public:
explicit FdWatchController(const Location& from_here): FdWatchControllerInterface(from_here) {}

FdWatchController(const FdWatchController&) = delete;
FdWatchController& operator=(const FdWatchController&) = delete;

~FdWatchController() override {}

bool StopWatchingFileDescriptor() override {}
};

bool WatchFileDescriptor(int fd,
bool persistent,
int mode,
FdWatchController* controller,
FdWatcher* delegate) {}

MessagePumpUIStarboard();
virtual ~MessagePumpUIStarboard() { Quit(); }

Expand Down Expand Up @@ -83,6 +105,9 @@ class BASE_EXPORT MessagePumpUIStarboard : public MessagePump {
// If the delegate has been removed, Quit() has been called.
bool should_quit() const { return delegate_ == nullptr; }

// Maintain a RunLoop attached to the starboard thread.
std::unique_ptr<RunLoop> run_loop_;

// The MessagePump::Delegate configured in Start().
Delegate* delegate_;

Expand Down
6 changes: 6 additions & 0 deletions base/run_loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,12 @@ class BASE_EXPORT RunLoop {
friend class MessagePumpUIApplication;
#endif

#if BUILDFLAG(IS_STARBOARD)
// Starboard doesn't support the blocking RunLoop::Run, so it calls
// BeforeRun and AfterRun directly.
friend class MessagePumpUIStarboard;
#endif // BUILDFLAG(IS_STARBOARD)

// Support for //base/test/scoped_run_loop_timeout.h.
friend class test::ScopedRunLoopTimeout;
friend class test::ScopedDisableRunLoopTimeout;
Expand Down
2 changes: 1 addition & 1 deletion base/task/current_thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ MessagePumpForUI* CurrentUIThread::GetMessagePumpForUI() const {
return static_cast<MessagePumpForUI*>(current_->GetMessagePump());
}

#if BUILDFLAG(IS_OZONE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_OZONE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_STARBOARD)
bool CurrentUIThread::WatchFileDescriptor(
int fd,
bool persistent,
Expand Down
11 changes: 10 additions & 1 deletion base/task/current_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,16 @@ class BASE_EXPORT CurrentUIThread : public CurrentThread {

CurrentUIThread* operator->() { return this; }

#if BUILDFLAG(IS_OZONE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN)
// TODO (cobalt b/393772370): Remove when x11/wayland are disabled.
#if BUILDFLAG(IS_STARBOARD)
bool WatchFileDescriptor(int fd,
bool persistent,
MessagePumpForUI::Mode mode,
MessagePumpForUI::FdWatchController* controller,
MessagePumpForUI::FdWatcher* delegate) { return false; }
#endif

#if BUILDFLAG(IS_OZONE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_STARBOARD)
static_assert(
std::is_base_of<WatchableIOMessagePumpPosix, MessagePumpForUI>::value,
"CurrentThreadForUI::WatchFileDescriptor is supported only"
Expand Down
8 changes: 8 additions & 0 deletions base/task/sequence_manager/sequence_manager_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,14 @@ void SequenceManagerImpl::BindToMessagePump(std::unique_ptr<MessagePump> pump) {
controller_->AttachToMessagePump();
}
#endif

// On Starboard attach to the Starboard loop.
#if BUILDFLAG(IS_STARBOARD)
if (settings_.message_loop_type == MessagePumpType::UI) {
controller_->AttachToMessagePump();
}
#endif // BUILDFLAG(IS_STARBOARD)

}

void SequenceManagerImpl::BindToCurrentThread() {
Expand Down
2 changes: 1 addition & 1 deletion base/task/sequence_manager/thread_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class BASE_EXPORT ThreadController {
// Returns true if the current run loop should quit when idle.
virtual bool ShouldQuitRunLoopWhenIdle() = 0;

#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_STARBOARD)
// On iOS, the main message loop cannot be Run(). Instead call
// AttachToMessagePump(), which connects this ThreadController to the
// UI thread's CFRunLoop and allows PostTask() to work.
Expand Down
4 changes: 2 additions & 2 deletions base/task/sequence_manager/thread_controller_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -363,11 +363,11 @@ MessagePump* ThreadControllerImpl::GetBoundMessagePump() const {
return nullptr;
}

#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_STARBOARD)
void ThreadControllerImpl::AttachToMessagePump() {
NOTREACHED();
}
#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_STARBOARD)

#if BUILDFLAG(IS_IOS)
void ThreadControllerImpl::DetachFromMessagePump() {
Expand Down
2 changes: 1 addition & 1 deletion base/task/sequence_manager/thread_controller_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class BASE_EXPORT ThreadControllerImpl : public ThreadController,
void SetTaskExecutionAllowed(bool allowed) override;
bool IsTaskExecutionAllowed() const override;
MessagePump* GetBoundMessagePump() const override;
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_STARBOARD)
void AttachToMessagePump() override;
#endif
#if BUILDFLAG(IS_IOS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,10 @@ void ThreadControllerWithMessagePumpImpl::AttachToMessagePump() {
main_thread_only().can_change_batch_size = false;
static_cast<MessagePumpForUI*>(pump_.get())->Attach(this);
}
#elif BUILDFLAG(IS_STARBOARD)
void ThreadControllerWithMessagePumpImpl::AttachToMessagePump() {
static_cast<MessagePumpForUI*>(pump_.get())->Attach(this);
}
#endif

bool ThreadControllerWithMessagePumpImpl::ShouldQuitRunLoopWhenIdle() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class BASE_EXPORT ThreadControllerWithMessagePumpImpl
bool IsTaskExecutionAllowed() const override;
MessagePump* GetBoundMessagePump() const override;
void PrioritizeYieldingToNative(base::TimeTicks prioritize_until) override;
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_STARBOARD)
void AttachToMessagePump() override;
#endif
#if BUILDFLAG(IS_IOS)
Expand Down
6 changes: 6 additions & 0 deletions base/test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ static_library("test_support") {
]
}

if (is_starboard) {
sources += [
"test_support_starboard.cc",
"test_support_starboard.h",
]
}
if (is_android) {
sources += [
"android/java_handler_thread_helpers.cc",
Expand Down
7 changes: 7 additions & 0 deletions base/test/test_suite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
#include "base/allocator/partition_alloc_support.h"
#endif // BUILDFLAG(USE_PARTITION_ALLOC)

#if BUILDFLAG(IS_STARBOARD)
#include "base/test/test_support_starboard.h"
#endif
namespace base {

namespace {
Expand Down Expand Up @@ -624,6 +627,10 @@ void TestSuite::Initialize() {
InitAndroidTestMessageLoop();
#endif // else BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(IS_STARBOARD)
InitStarboardTestMessageLoop();
#endif

CHECK(debug::EnableInProcessStackDumping());
#if BUILDFLAG(IS_WIN)
RouteStdioToConsole(true);
Expand Down
64 changes: 64 additions & 0 deletions base/test/test_support_starboard.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/singleton.h"
#include "base/message_loop/message_pump.h"
#include "base/message_loop/message_pump_default.h"
#include "base/message_loop/message_pump_for_ui.h"
#include "base/synchronization/waitable_event.h"

namespace {

class MessagePumpForUIStub : public base::MessagePumpUIStarboard {
public:

MessagePumpForUIStub() : base::MessagePumpForUI(), default_pump_ (new base::MessagePumpDefault) { }
~MessagePumpForUIStub() override {}

// Similar to Android, in Starboad tests there isn't a native thread,
// as such RunLoop::Run() should be used to run the loop instead of attaching
// and delegating to the native loop.
// As such, this override ignores the Attach() request.
void Attach(base::MessagePump::Delegate* delegate) override {}

// --- Delegate to the MessagePumpDefault Implementation ---

virtual void Run(Delegate* delegate) override {
default_pump_->Run(delegate);
}

virtual void Quit() override {
default_pump_->Quit();
}

virtual void ScheduleWork() override {
default_pump_->ScheduleWork();
}

virtual void ScheduleDelayedWork(
const Delegate::NextWorkInfo& next_work_info) override {
default_pump_->ScheduleDelayedWork(next_work_info);
}

private:
std::unique_ptr<base::MessagePumpDefault> default_pump_;
};

std::unique_ptr<base::MessagePump> CreateMessagePumpForUIStub() {
return std::unique_ptr<base::MessagePump>(new MessagePumpForUIStub());
}

} // namespace

namespace base {


void InitStarboardTestMessageLoop() {
if (!MessagePump::IsMessagePumpForUIFactoryOveridden())
MessagePump::OverrideMessagePumpForUIFactory(&CreateMessagePumpForUIStub);
}

} // namespace base
15 changes: 15 additions & 0 deletions base/test/test_support_starboard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_TEST_TEST_SUPPORT_STARBOARD_H_
#define BASE_TEST_TEST_SUPPORT_STARBOARD_H_

namespace base {

// Init the message loop for tests on Starboard.
void InitStarboardTestMessageLoop();

} // namespace base

#endif // BASE_TEST_TEST_SUPPORT_STARBOARD_H_
8 changes: 4 additions & 4 deletions base/threading/thread_restrictions.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,9 @@ class BrowserGpuChannelHostFactory;
class BrowserMainLoop;
class BrowserProcessIOThread;
class BrowserTestBase;
#if BUILDFLAG(IS_IOS)
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_STARBOARD)
class ContentMainRunnerImpl;
#endif // BUILDFLAG(IS_IOS)
#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_STARBOARD)
class DesktopCaptureDevice;
class DWriteFontCollectionProxy;
class DWriteFontProxyImpl;
Expand Down Expand Up @@ -1006,9 +1006,9 @@ class BASE_EXPORT PermanentThreadAllowance {
friend class base::TestCustomDisallow;
friend class content::BrowserMainLoop;
friend class content::BrowserTestBase;
#if BUILDFLAG(IS_IOS)
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_STARBOARD)
friend class content::ContentMainRunnerImpl;
#endif // BUILDFLAG(IS_IOS)
#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_STARBOARD)
friend class web::WebMainLoop;

static void AllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
Expand Down
4 changes: 3 additions & 1 deletion build/config/ozone.gni
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ declare_args() {
ozone_platform_wayland = true
} else if (is_linux) {
ozone_platform = "x11"
ozone_platform_wayland = true
if (!is_starboard) {
ozone_platform_wayland = true
}
ozone_platform_x11 = true
} else if (is_fuchsia) {
ozone_platform = "flatland"
Expand Down
Loading

0 comments on commit aa99278

Please sign in to comment.