From 1d025620e3344e3cc9aee26fe815d8675e4f9810 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Tue, 24 Mar 2026 07:28:28 +0100 Subject: [PATCH] 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. --- Libraries/LibIPC/CMakeLists.txt | 1 + Libraries/LibIPC/Forward.h | 1 + .../MachBootstrapListener.cpp} | 26 +++++++++---------- .../MachBootstrapListener.h} | 13 +++++----- .../MachBootstrapMessages.h} | 2 +- Libraries/LibIPC/TransportBootstrapMach.cpp | 14 +++++----- Libraries/LibWebView/Application.cpp | 6 ++--- Libraries/LibWebView/Application.h | 2 +- Libraries/LibWebView/CMakeLists.txt | 11 ++++---- Libraries/LibWebView/Forward.h | 4 --- Services/WebDriver/Session.cpp | 2 +- Services/WebDriver/Session.h | 4 +-- 12 files changed, 42 insertions(+), 44 deletions(-) rename Libraries/{LibWebView/MachPortServer.cpp => LibIPC/MachBootstrapListener.cpp} (82%) rename Libraries/{LibWebView/MachPortServer.h => LibIPC/MachBootstrapListener.h} (76%) rename Libraries/{LibCore/Platform/MachMessageTypes.h => LibIPC/MachBootstrapMessages.h} (97%) diff --git a/Libraries/LibIPC/CMakeLists.txt b/Libraries/LibIPC/CMakeLists.txt index 2c2f57ad25..095ac9aac1 100644 --- a/Libraries/LibIPC/CMakeLists.txt +++ b/Libraries/LibIPC/CMakeLists.txt @@ -10,6 +10,7 @@ if (APPLE AND NOT IOS) list(APPEND SOURCES AttachmentMachPort.cpp File.cpp + MachBootstrapListener.cpp Message.cpp TransportBootstrapMach.cpp TransportMachPort.cpp) diff --git a/Libraries/LibIPC/Forward.h b/Libraries/LibIPC/Forward.h index 157b21819a..ca52aad5e6 100644 --- a/Libraries/LibIPC/Forward.h +++ b/Libraries/LibIPC/Forward.h @@ -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) diff --git a/Libraries/LibWebView/MachPortServer.cpp b/Libraries/LibIPC/MachBootstrapListener.cpp similarity index 82% rename from Libraries/LibWebView/MachPortServer.cpp rename to Libraries/LibIPC/MachBootstrapListener.cpp index 6bb38cba71..f9c73e485e 100644 --- a/Libraries/LibWebView/MachPortServer.cpp +++ b/Libraries/LibIPC/MachBootstrapListener.cpp @@ -5,14 +5,14 @@ */ #include -#include +#include +#include #include -#include -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 MachPortServer::allocate_server_port() +ErrorOr 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 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); diff --git a/Libraries/LibWebView/MachPortServer.h b/Libraries/LibIPC/MachBootstrapListener.h similarity index 76% rename from Libraries/LibWebView/MachPortServer.h rename to Libraries/LibIPC/MachBootstrapListener.h index 0e4903cc83..8964a8ce0c 100644 --- a/Libraries/LibWebView/MachPortServer.h +++ b/Libraries/LibIPC/MachBootstrapListener.h @@ -7,23 +7,24 @@ #pragma once #include +#include #include #include #include #include -#include #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(); diff --git a/Libraries/LibCore/Platform/MachMessageTypes.h b/Libraries/LibIPC/MachBootstrapMessages.h similarity index 97% rename from Libraries/LibCore/Platform/MachMessageTypes.h rename to Libraries/LibIPC/MachBootstrapMessages.h index 366de8043e..6b1799dce1 100644 --- a/Libraries/LibCore/Platform/MachMessageTypes.h +++ b/Libraries/LibIPC/MachBootstrapMessages.h @@ -16,7 +16,7 @@ #include -namespace Core::Platform { +namespace IPC { struct MessageBodyWithSelfTaskPort { mach_msg_body_t body; diff --git a/Libraries/LibIPC/TransportBootstrapMach.cpp b/Libraries/LibIPC/TransportBootstrapMach.cpp index 3441a1c888..33858909c4 100644 --- a/Libraries/LibIPC/TransportBootstrapMach.cpp +++ b/Libraries/LibIPC/TransportBootstrapMach.cpp @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include #include @@ -20,12 +20,12 @@ ErrorOr 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 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 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; diff --git a/Libraries/LibWebView/Application.cpp b/Libraries/LibWebView/Application.cpp index 85f03c087c..f1682b5737 100644 --- a/Libraries/LibWebView/Application.cpp +++ b/Libraries/LibWebView/Application.cpp @@ -27,9 +27,9 @@ #include #if defined(AK_OS_MACOS) +# include # include # include -# include #endif namespace WebView { @@ -103,10 +103,10 @@ ErrorOr Application::initialize(Main::Arguments const& arguments) #endif #if defined(AK_OS_MACOS) - m_mach_port_server = make(mach_server_name_for_process("Ladybird"sv, Core::System::getpid())); + m_mach_port_server = make(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( diff --git a/Libraries/LibWebView/Application.h b/Libraries/LibWebView/Application.h index 4e8e036efd..ea8b52da1d 100644 --- a/Libraries/LibWebView/Application.h +++ b/Libraries/LibWebView/Application.h @@ -294,7 +294,7 @@ private: FileDownloader m_file_downloader; #if defined(AK_OS_MACOS) - OwnPtr m_mach_port_server; + OwnPtr m_mach_port_server; IPC::TransportBootstrapMachServer m_transport_bootstrap_server; Function)> m_on_browser_process_transport; #endif diff --git a/Libraries/LibWebView/CMakeLists.txt b/Libraries/LibWebView/CMakeLists.txt index 825eb444e2..f99dc6c4a3 100644 --- a/Libraries/LibWebView/CMakeLists.txt +++ b/Libraries/LibWebView/CMakeLists.txt @@ -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) diff --git a/Libraries/LibWebView/Forward.h b/Libraries/LibWebView/Forward.h index 6cba413db8..42afdc83fb 100644 --- a/Libraries/LibWebView/Forward.h +++ b/Libraries/LibWebView/Forward.h @@ -25,10 +25,6 @@ class ViewImplementation; class WebContentClient; class WebUI; -#if defined(AK_OS_MACOS) -class MachPortServer; -#endif - struct Attribute; struct AutocompleteEngine; struct BrowserOptions; diff --git a/Services/WebDriver/Session.cpp b/Services/WebDriver/Session.cpp index fdb66c57b5..c8b230284a 100644 --- a/Services/WebDriver/Session.cpp +++ b/Services/WebDriver/Session.cpp @@ -271,7 +271,7 @@ ErrorOr Session::create_server(NonnullRefPtr promise) dbgln("Listening for WebDriver connection on {}", m_web_content_endpoint); #if defined(AK_OS_MACOS) - m_web_content_mach_port_server = make(m_web_content_endpoint); + m_web_content_mach_port_server = make(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"); diff --git a/Services/WebDriver/Session.h b/Services/WebDriver/Session.h index baab0a3572..a72b794db2 100644 --- a/Services/WebDriver/Session.h +++ b/Services/WebDriver/Session.h @@ -19,8 +19,8 @@ #if !defined(AK_OS_MACOS) # include #else +# include # include -# include #endif #include #include @@ -115,7 +115,7 @@ private: NonnullRefPtr m_event_loop; #if defined(AK_OS_MACOS) - OwnPtr m_web_content_mach_port_server; + OwnPtr m_web_content_mach_port_server; IPC::TransportBootstrapMachServer m_transport_bootstrap_server; #else RefPtr m_web_content_server;