LibWeb: Send IPC messages exceeding socket buffer through shared memory

It turned out that some web applications want to send fairly large
messages to WebWorker through IPC (for example, MapLibre GL sends
~1200KiB), which led to failures (at least on macOS) because buffer size
of TransportSocket is limited to 128KiB. This change solves the problem
by wrapping messages that exceed socket buffer size into another message
that holds wrapped message content in shared memory.

Co-Authored-By: Luke Wilde <luke@ladybird.org>
This commit is contained in:
Aliaksandr Kalenik 2025-04-03 02:55:11 +02:00 committed by Andreas Kling
commit 4b04e97feb
Notes: github-actions[bot] 2025-04-03 11:56:37 +00:00
11 changed files with 173 additions and 18 deletions

View file

@ -13,6 +13,7 @@
#include <LibIPC/File.h>
#include <LibIPC/Forward.h>
#include <LibIPC/Transport.h>
#include <LibIPC/UnprocessedFileDescriptors.h>
#include <LibThreading/ConditionVariable.h>
#include <LibThreading/MutexProtected.h>
#include <LibThreading/Thread.h>
@ -27,7 +28,7 @@ public:
[[nodiscard]] bool is_open() const;
ErrorOr<void> post_message(Message const&);
ErrorOr<void> post_message(MessageBuffer);
ErrorOr<void> post_message(u32 endpoint_magic, MessageBuffer);
void shutdown();
virtual void die() { }
@ -40,7 +41,7 @@ protected:
virtual void may_have_become_unresponsive() { }
virtual void did_become_responsive() { }
virtual void shutdown_with_error(Error const&);
virtual OwnPtr<Message> try_parse_message(ReadonlyBytes, Queue<IPC::File>&) = 0;
virtual OwnPtr<Message> try_parse_message(ReadonlyBytes, UnprocessedFileDescriptors&) = 0;
OwnPtr<IPC::Message> wait_for_specific_endpoint_message_impl(u32 endpoint_magic, int message_id);
void wait_for_transport_to_become_readable();
@ -57,7 +58,7 @@ protected:
RefPtr<Core::Timer> m_responsiveness_timer;
Vector<NonnullOwnPtr<Message>> m_unprocessed_messages;
Queue<IPC::File> m_unprocessed_fds; // unused on Windows
UnprocessedFileDescriptors m_unprocessed_fds;
ByteBuffer m_unprocessed_bytes;
u32 m_local_endpoint_magic { 0 };
@ -113,7 +114,7 @@ protected:
return {};
}
virtual OwnPtr<Message> try_parse_message(ReadonlyBytes bytes, Queue<IPC::File>& fds) override
virtual OwnPtr<Message> try_parse_message(ReadonlyBytes bytes, UnprocessedFileDescriptors& fds) override
{
auto local_message = LocalEndpoint::decode_message(bytes, fds);
if (!local_message.is_error())