Commit Graph

17 Commits

Author SHA1 Message Date
Aliaksandr Kalenik
509c86dca0 LibIPC: Simplify IPC read hook
- Return `PeerEOF` enum instead of `Error` containing string from
  `drain_messages_from_peer()`. There are no other error types to return
  from this function, so boolean-like enum is sufficient.
- Don't override read hook in `ConnectionFromClient` constructor. It was
  previously redefined only to suppress EOF error returned by
  `drain_messages_from_peer()`.
2025-10-21 09:31:22 +02:00
Rocco Corsi
b6b56910e8 LibIPC: Shutdown IPC handler when transport is lost during sync event
If the Ladybird process crashes or just ends normally, the IPC transport
connection with WebContent may be shutdown after a send sync event (for
example: WebContentClient DidRequestCookie) was sent from WebContent,
but before the Ladybird process provided the matching sync event
response (for example: WebContentClient DidRequestCookieResponse). This
can lead to a runaway WebContent process if other IPC events (for
example: WebContentServer DidPaint, or SetSystemVisibilityState, or
MouseEvent, or CloseServer, etc...) are also queued when the IPC
connection is shutdown.

At the core of the issue is that the loop waiting for the matching
send sync response will prioritize waiting for the response and remain
spinning even if the IPC connection is reporting that it was shutdown,
but only if there happens to be other unrelated events received before
the IPC shutdown is detected. These unrelated events will not be
processed because the loop is stuck waiting for the response that due
to the Ladybird process having stopped, will never be sent.

Because the shutdown of the IPC connection is not handled when other
events happen to be also present, new events may be posted for transfer
by the WebContent process if the page is very active. If many new events
are posted this could lead to a slow or very quick memory leak in the
WebContent process due to the queue growing large, sometimes all the way
to total system memory exhaustion. If no events or only a few new events
are sent, then the leak may be hard to detect.

This PR fixes the faulty IPC shutdown handling by not getting stuck if
any messages are present in the receive queue. Before returning to the
caller any remaining messages will be immediately processed.
2025-10-07 17:04:32 -05:00
Aliaksandr Kalenik
93d7efa4c3 LibIPC: Delete unused code in Connection 2025-10-01 14:59:23 -04:00
Jelle Raaijmakers
63119355e3 LibIPC: Do not try to send a response back if transport was closed
The local handling of some messages might cause the transport to get
closed. If that's the case, we shouldn't try to send back a response.

This fixes many of the "Trying to post_message during IPC shutdown"
errors I was seeing when terminating Ladybird or when abnormally exiting
from LibWeb tests.
2025-08-17 20:51:56 -04:00
stasoid
8af2a49b5c LibIPC: Make TransportSocketWindows responsible for reading entire
messages. Port of a371f84 to Windows.
2025-06-17 15:36:47 -06:00
Aliaksandr Kalenik
b53694b4c0 LibIPC+LibWeb: Delete LargeMessageWrapper workaround in IPC connection
Bring back 2d625f5c23
2025-04-10 23:40:02 +02:00
Tim Ledbetter
1ee56d34e7 Revert "LibIPC+LibWeb: Delete LargeMessageWrapper workaround in IPC…
…connection"

This reverts commit 2d625f5c23.
2025-04-10 16:24:38 +01:00
Aliaksandr Kalenik
2d625f5c23 LibIPC+LibWeb: Delete LargeMessageWrapper workaround in IPC connection
It's no longer needed because TransportSocket is now capable of properly
sending large messages.
2025-04-10 01:30:08 +02:00
Aliaksandr Kalenik
db8c443392 Everywhere: Make TransportSocket non-movable
Instead of wrapping all non-movable members of TransportSocket in OwnPtr
to keep it movable, make TransportSocket itself non-movable and wrap it
in OwnPtr.
2025-04-09 15:27:52 +02:00
Aliaksandr Kalenik
14bac7b287 LibIPC: Move send thread from IPC connection to the transport layer
By doing this we also make MessagePort, that relies on IPC transport,
to send messages from separate thread, which solves the problem when
WebWorker and WebContent could deadlock if both were trying to post
messages at the same time.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/4254
2025-04-08 21:09:24 +02:00
Aliaksandr Kalenik
ab35325003 LibIPC: Move early fd deallocation workaround to the transport layer
Reimplements c3121c9d at the transport layer, allowing us to solve the
same problem once, in a single place, for both the LibIPC connection and
MessagePort. This avoids exposing a workaround for a macOS specific Unix
domain socket issue to higher abstraction layers.
2025-04-08 21:09:24 +02:00
Aliaksandr Kalenik
3525467e56 LibIPC: Join send thread instead of detaching in ~ConnectionBase()
By doing this we ensure that sending thread won't try to write into a
closed socket.
2025-04-08 21:09:24 +02:00
Aliaksandr Kalenik
a371f849e3 LibIPC: Make TransportSocket responsible for reading entire messages
With this change, the responsibility for prepending messages with their
size and ensuring the entire message is received before returning it to
the caller is moved to TransportSocket. This removes the need to
duplicate this logic in both LibIPC and MessagePort.

Another advantage of reducing message granularity at IPC::Transport
layer is that it will make it easier to support alternative transport
implementations (like Mach ports, which unlike Unix domain sockets are
not stream oriented).
2025-04-07 16:59:49 +02:00
Aliaksandr Kalenik
c3121c9d8a LibIPC+Meta: Keep message buffer alive until acknowledged by peer
This change ensures that instead of immediately deallocating the message
buffer after sending, we retain it in an acknowledgement wait queue
until an acknowledgement is received from the peer. This is necessary
to handle a behavior of the macOS kernel, which may prematurely
garbage-collect file descriptors contained within the message buffer
before the peer receives them.

The acknowledgement mechanism assumes messages are received in the same
order they were sent so, each acknowledgement message simply indicates
the count of successfully received messages, specifying how many entries
can safely be removed from the acknowledgement wait queue.
2025-04-05 23:14:32 +02:00
Aliaksandr Kalenik
4b04e97feb 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>
2025-04-03 13:55:41 +02:00
Timothy Flynn
cf69f52d53 LibIPC+Everywhere: Always pass ownership of transferred data to clients
This has been a longstanding ergonomic issue with our IPC compiler. Non-
trivial types were previously passed by const&. So if we wanted to avoid
expensive copies, we would have to const_cast and move the data.

We now pass ownership of all transferred data to the client subclasses.
This allows us to remove const_cast from these methods, and allows us to
avoid some trivial expensive copies that we didn't bother to const_cast.
2025-03-09 11:14:20 -04:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00