mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
Everywhere: Move Mach bootstrap listener into LibIPC
Move MachPortServer from LibWebView into LibIPC as MachBootstrapListener and move the Mach message structs from MachMessageTypes.h into LibIPC. These types are IPC infrastructure, not UI or platform concerns. Consolidating them in LibIPC keeps the Mach bootstrap handshake self-contained in a single library and removes LibWebView's dependency on LibThreading.
This commit is contained in:
committed by
Alexander Kalenik
parent
e47f4cf90f
commit
1d025620e3
Notes:
github-actions[bot]
2026-03-24 18:53:16 +00:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/LadybirdBrowser/ladybird/commit/1d025620e33 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8599
@@ -10,6 +10,7 @@ if (APPLE AND NOT IOS)
|
||||
list(APPEND SOURCES
|
||||
AttachmentMachPort.cpp
|
||||
File.cpp
|
||||
MachBootstrapListener.cpp
|
||||
Message.cpp
|
||||
TransportBootstrapMach.cpp
|
||||
TransportMachPort.cpp)
|
||||
|
||||
@@ -22,6 +22,7 @@ class Stub;
|
||||
class TransportHandle;
|
||||
|
||||
#if defined(AK_OS_MACOS)
|
||||
class MachBootstrapListener;
|
||||
class TransportMachPort;
|
||||
using Transport = TransportMachPort;
|
||||
#elif !defined(AK_OS_WINDOWS)
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
*/
|
||||
|
||||
#include <AK/Debug.h>
|
||||
#include <LibCore/Platform/MachMessageTypes.h>
|
||||
#include <LibIPC/MachBootstrapListener.h>
|
||||
#include <LibIPC/MachBootstrapMessages.h>
|
||||
#include <LibThreading/Thread.h>
|
||||
#include <LibWebView/MachPortServer.h>
|
||||
|
||||
namespace WebView {
|
||||
namespace IPC {
|
||||
|
||||
MachPortServer::MachPortServer(ByteString server_port_name)
|
||||
: m_thread(Threading::Thread::construct("MachPortServer"sv, [this]() -> intptr_t { thread_loop(); return 0; }))
|
||||
MachBootstrapListener::MachBootstrapListener(ByteString server_port_name)
|
||||
: m_thread(Threading::Thread::construct("MachBootstrapListener"sv, [this]() -> intptr_t { thread_loop(); return 0; }))
|
||||
, m_server_port_name(move(server_port_name))
|
||||
{
|
||||
if (auto err = allocate_server_port(); err.is_error())
|
||||
@@ -21,29 +21,29 @@ MachPortServer::MachPortServer(ByteString server_port_name)
|
||||
start();
|
||||
}
|
||||
|
||||
MachPortServer::~MachPortServer()
|
||||
MachBootstrapListener::~MachBootstrapListener()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void MachPortServer::start()
|
||||
void MachBootstrapListener::start()
|
||||
{
|
||||
m_thread->start();
|
||||
}
|
||||
|
||||
void MachPortServer::stop()
|
||||
void MachBootstrapListener::stop()
|
||||
{
|
||||
// FIXME: We should join instead (after storing should_stop = false) when we have a way to interrupt the thread's mach_msg call
|
||||
m_thread->detach();
|
||||
m_should_stop.store(true, MemoryOrder::memory_order_release);
|
||||
}
|
||||
|
||||
bool MachPortServer::is_initialized()
|
||||
bool MachBootstrapListener::is_initialized()
|
||||
{
|
||||
return MACH_PORT_VALID(m_server_port_recv_right.port()) && MACH_PORT_VALID(m_server_port_send_right.port());
|
||||
}
|
||||
|
||||
ErrorOr<void> MachPortServer::allocate_server_port()
|
||||
ErrorOr<void> MachBootstrapListener::allocate_server_port()
|
||||
{
|
||||
m_server_port_recv_right = TRY(Core::MachPort::create_with_right(Core::MachPort::PortRight::Receive));
|
||||
m_server_port_send_right = TRY(m_server_port_recv_right.insert_right(Core::MachPort::MessageRight::MakeSend));
|
||||
@@ -53,10 +53,10 @@ ErrorOr<void> MachPortServer::allocate_server_port()
|
||||
return {};
|
||||
}
|
||||
|
||||
void MachPortServer::thread_loop()
|
||||
void MachBootstrapListener::thread_loop()
|
||||
{
|
||||
while (!m_should_stop.load(MemoryOrder::memory_order_acquire)) {
|
||||
Core::Platform::ReceivedMachMessage message {};
|
||||
ReceivedMachMessage message {};
|
||||
|
||||
// Get the pid of the child from the audit trailer so we can associate the port w/it
|
||||
mach_msg_options_t const options = MACH_RCV_MSG | MACH_RCV_TRAILER_TYPE(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT);
|
||||
@@ -68,7 +68,7 @@ void MachPortServer::thread_loop()
|
||||
break;
|
||||
}
|
||||
|
||||
if (message.header.msgh_id == Core::Platform::SELF_TASK_PORT_MESSAGE_ID) {
|
||||
if (message.header.msgh_id == SELF_TASK_PORT_MESSAGE_ID) {
|
||||
auto const& task_port_message = message.body;
|
||||
VERIFY(MACH_MSGH_BITS_LOCAL(message.header.msgh_bits) == MACH_MSG_TYPE_MOVE_SEND);
|
||||
VERIFY(task_port_message.body.msgh_descriptor_count == 1);
|
||||
@@ -7,23 +7,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <AK/Atomic.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCore/MachPort.h>
|
||||
#include <LibThreading/Forward.h>
|
||||
#include <LibWebView/Forward.h>
|
||||
|
||||
#if !defined(AK_OS_MACH)
|
||||
# error "This file is only for Mach kernel-based OS's"
|
||||
# error "MachBootstrapListener is only available on Mach kernel-based OS's"
|
||||
#endif
|
||||
|
||||
namespace WebView {
|
||||
namespace IPC {
|
||||
|
||||
class WEBVIEW_API MachPortServer {
|
||||
class MachBootstrapListener {
|
||||
AK_MAKE_NONCOPYABLE(MachBootstrapListener);
|
||||
|
||||
public:
|
||||
explicit MachPortServer(ByteString server_port_name);
|
||||
~MachPortServer();
|
||||
explicit MachBootstrapListener(ByteString server_port_name);
|
||||
~MachBootstrapListener();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include <mach/mach.h>
|
||||
|
||||
namespace Core::Platform {
|
||||
namespace IPC {
|
||||
|
||||
struct MessageBodyWithSelfTaskPort {
|
||||
mach_msg_body_t body;
|
||||
@@ -8,8 +8,8 @@
|
||||
#include <AK/ByteString.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <LibCore/MachPort.h>
|
||||
#include <LibCore/Platform/MachMessageTypes.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibIPC/MachBootstrapMessages.h>
|
||||
#include <LibIPC/TransportBootstrapMach.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
@@ -20,12 +20,12 @@ ErrorOr<TransportBootstrapMachPorts> bootstrap_transport_from_server_port(Core::
|
||||
{
|
||||
auto reply_port = TRY(Core::MachPort::create_with_right(Core::MachPort::PortRight::Receive));
|
||||
|
||||
Core::Platform::MessageWithSelfTaskPort message {};
|
||||
MessageWithSelfTaskPort message {};
|
||||
message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE) | MACH_MSGH_BITS_COMPLEX;
|
||||
message.header.msgh_size = sizeof(message);
|
||||
message.header.msgh_remote_port = server_port.port();
|
||||
message.header.msgh_local_port = reply_port.port();
|
||||
message.header.msgh_id = Core::Platform::SELF_TASK_PORT_MESSAGE_ID;
|
||||
message.header.msgh_id = SELF_TASK_PORT_MESSAGE_ID;
|
||||
message.body.msgh_descriptor_count = 1;
|
||||
message.port_descriptor.name = mach_task_self();
|
||||
message.port_descriptor.disposition = MACH_MSG_TYPE_COPY_SEND;
|
||||
@@ -36,14 +36,14 @@ ErrorOr<TransportBootstrapMachPorts> bootstrap_transport_from_server_port(Core::
|
||||
if (send_result != KERN_SUCCESS)
|
||||
return Core::mach_error_to_error(send_result);
|
||||
|
||||
Core::Platform::ReceivedIPCChannelPortsMessage reply {};
|
||||
ReceivedIPCChannelPortsMessage reply {};
|
||||
mach_msg_timeout_t const reply_timeout = 5000;
|
||||
auto const recv_result = mach_msg(&reply.header, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(reply),
|
||||
reply_port.port(), reply_timeout, MACH_PORT_NULL);
|
||||
if (recv_result != KERN_SUCCESS)
|
||||
return Core::mach_error_to_error(recv_result);
|
||||
|
||||
VERIFY(reply.header.msgh_id == Core::Platform::IPC_CHANNEL_PORTS_MESSAGE_ID);
|
||||
VERIFY(reply.header.msgh_id == IPC_CHANNEL_PORTS_MESSAGE_ID);
|
||||
VERIFY(reply.body.msgh_descriptor_count == 2);
|
||||
VERIFY(reply.receive_port.type == MACH_MSG_PORT_DESCRIPTOR);
|
||||
VERIFY(reply.receive_port.disposition == MACH_MSG_TYPE_MOVE_RECEIVE);
|
||||
@@ -64,12 +64,12 @@ ErrorOr<TransportBootstrapMachPorts> bootstrap_transport_from_mach_server(String
|
||||
|
||||
void TransportBootstrapMachServer::send_transport_ports_to_child(Core::MachPort reply_port, TransportBootstrapMachPorts ports)
|
||||
{
|
||||
Core::Platform::MessageWithIPCChannelPorts message {};
|
||||
MessageWithIPCChannelPorts message {};
|
||||
message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0) | MACH_MSGH_BITS_COMPLEX;
|
||||
message.header.msgh_size = sizeof(message);
|
||||
message.header.msgh_remote_port = reply_port.release();
|
||||
message.header.msgh_local_port = MACH_PORT_NULL;
|
||||
message.header.msgh_id = Core::Platform::IPC_CHANNEL_PORTS_MESSAGE_ID;
|
||||
message.header.msgh_id = IPC_CHANNEL_PORTS_MESSAGE_ID;
|
||||
message.body.msgh_descriptor_count = 2;
|
||||
message.receive_port.name = ports.receive_right.release();
|
||||
message.receive_port.disposition = MACH_MSG_TYPE_MOVE_RECEIVE;
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
#include <LibWebView/WebContentClient.h>
|
||||
|
||||
#if defined(AK_OS_MACOS)
|
||||
# include <LibIPC/MachBootstrapListener.h>
|
||||
# include <LibIPC/Transport.h>
|
||||
# include <LibIPC/TransportBootstrapMach.h>
|
||||
# include <LibWebView/MachPortServer.h>
|
||||
#endif
|
||||
|
||||
namespace WebView {
|
||||
@@ -103,10 +103,10 @@ ErrorOr<void> Application::initialize(Main::Arguments const& arguments)
|
||||
#endif
|
||||
|
||||
#if defined(AK_OS_MACOS)
|
||||
m_mach_port_server = make<MachPortServer>(mach_server_name_for_process("Ladybird"sv, Core::System::getpid()));
|
||||
m_mach_port_server = make<IPC::MachBootstrapListener>(mach_server_name_for_process("Ladybird"sv, Core::System::getpid()));
|
||||
set_mach_server_name(m_mach_port_server->server_port_name());
|
||||
|
||||
m_mach_port_server->on_bootstrap_request = [this](MachPortServer::BootstrapRequest request) {
|
||||
m_mach_port_server->on_bootstrap_request = [this](IPC::MachBootstrapListener::BootstrapRequest request) {
|
||||
set_process_mach_port(request.pid, move(request.task_port));
|
||||
auto result = MUST(m_transport_bootstrap_server.handle_bootstrap_request(request.pid, move(request.reply_port)));
|
||||
result.visit(
|
||||
|
||||
@@ -294,7 +294,7 @@ private:
|
||||
FileDownloader m_file_downloader;
|
||||
|
||||
#if defined(AK_OS_MACOS)
|
||||
OwnPtr<MachPortServer> m_mach_port_server;
|
||||
OwnPtr<IPC::MachBootstrapListener> m_mach_port_server;
|
||||
IPC::TransportBootstrapMachServer m_transport_bootstrap_server;
|
||||
Function<void(NonnullOwnPtr<IPC::Transport>)> m_on_browser_process_transport;
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
include(fontconfig)
|
||||
|
||||
set(SOURCES
|
||||
Application.cpp
|
||||
Attribute.cpp
|
||||
@@ -31,10 +33,6 @@ set(SOURCES
|
||||
WebUI/SettingsUI.cpp
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
list(APPEND SOURCES MachPortServer.cpp)
|
||||
endif()
|
||||
|
||||
set(GENERATED_SOURCES ${CURRENT_LIB_GENERATED})
|
||||
|
||||
embed_as_string(
|
||||
@@ -70,8 +68,9 @@ set(GENERATED_SOURCES
|
||||
ladybird_lib(LibWebView webview EXPLICIT_SYMBOL_EXPORT)
|
||||
target_link_libraries(LibWebView PRIVATE LibCore LibDatabase LibDevTools LibFileSystem LibGfx LibHTTP LibImageDecoderClient LibIPC LibRequests LibJS LibWeb LibUnicode LibURL LibSyntax LibTextCodec)
|
||||
|
||||
if (APPLE)
|
||||
target_link_libraries(LibWebView PRIVATE LibThreading)
|
||||
# Third-party
|
||||
if (HAS_FONTCONFIG)
|
||||
target_link_libraries(LibWebView PRIVATE Fontconfig::Fontconfig)
|
||||
endif()
|
||||
|
||||
if (ENABLE_INSTALL_HEADERS)
|
||||
|
||||
@@ -25,10 +25,6 @@ class ViewImplementation;
|
||||
class WebContentClient;
|
||||
class WebUI;
|
||||
|
||||
#if defined(AK_OS_MACOS)
|
||||
class MachPortServer;
|
||||
#endif
|
||||
|
||||
struct Attribute;
|
||||
struct AutocompleteEngine;
|
||||
struct BrowserOptions;
|
||||
|
||||
@@ -271,7 +271,7 @@ ErrorOr<void> Session::create_server(NonnullRefPtr<ServerPromise> promise)
|
||||
dbgln("Listening for WebDriver connection on {}", m_web_content_endpoint);
|
||||
|
||||
#if defined(AK_OS_MACOS)
|
||||
m_web_content_mach_port_server = make<WebView::MachPortServer>(m_web_content_endpoint);
|
||||
m_web_content_mach_port_server = make<IPC::MachBootstrapListener>(m_web_content_endpoint);
|
||||
if (!m_web_content_mach_port_server->is_initialized())
|
||||
return Error::from_string_literal("Failed to initialize Mach port server for WebDriver");
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
#if !defined(AK_OS_MACOS)
|
||||
# include <LibCore/LocalServer.h>
|
||||
#else
|
||||
# include <LibIPC/MachBootstrapListener.h>
|
||||
# include <LibIPC/TransportBootstrapMach.h>
|
||||
# include <LibWebView/MachPortServer.h>
|
||||
#endif
|
||||
#include <LibCore/Process.h>
|
||||
#include <LibCore/Promise.h>
|
||||
@@ -115,7 +115,7 @@ private:
|
||||
NonnullRefPtr<Core::WeakEventLoopReference> m_event_loop;
|
||||
|
||||
#if defined(AK_OS_MACOS)
|
||||
OwnPtr<WebView::MachPortServer> m_web_content_mach_port_server;
|
||||
OwnPtr<IPC::MachBootstrapListener> m_web_content_mach_port_server;
|
||||
IPC::TransportBootstrapMachServer m_transport_bootstrap_server;
|
||||
#else
|
||||
RefPtr<Core::LocalServer> m_web_content_server;
|
||||
|
||||
Reference in New Issue
Block a user