Commit graph

111 commits

Author SHA1 Message Date
Aliaksandr Kalenik
466c793fdb LibIPC: Use AllocatingMemoryStream in TransportSocket send queue
Some checks are pending
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Memory stream is a more suitable container for the socket send queue,
as using it results in fewer allocations than trying to emulate a stream
using a Vector.
2025-04-15 18:48:53 +02:00
Aliaksandr Kalenik
b53694b4c0 LibIPC+LibWeb: Delete LargeMessageWrapper workaround in IPC connection
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Bring back 2d625f5c23
2025-04-10 23:40:02 +02:00
Aliaksandr Kalenik
681333d329 LibIPC: Protect underlying socket of TransportSocket with RWLock
This is necessary to prevent the socket from being closed while it is
being used for reading or writing.
2025-04-10 23:40:02 +02:00
Aliaksandr Kalenik
14dc7686c3 LibIPC: Change TransportSocket to write large messages in small chunks
Bring back d6080d1fdc with a missing check
whether underlying socket is closed, before accessing `fd()` that is
optional and empty in case of closed socket.
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
Tim Ledbetter
3fcdbef327 Revert "LibIPC: Change TransportSocket to write large messages in…"
…small chunks.

This reverts commit d6080d1fdc.
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
d6080d1fdc LibIPC: Change TransportSocket to write large messages in small chunks
With this change TransportSocket becomes capable of sending large
messages without relying on workarounds, such as sending the message as
a shared memory file descriptor when it can't fully fit into the socket
buffer.

It's implemented by combining all enqueued messages into two buffers:
one for bytes and another for fds, and repeatedly attempts to write them
in smaller chunks, waiting for the socket to become writable again if
the receiver needs time to consume the data.

Another significant improvement brought by this change is that we no
longer drop messages queued for sending if the socket doesn't become
writable after a 100ms timeout. Instead, we return the message to the
send buffer and continue waiting for the socket to become writable.
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
ac643aa392 LibIPC: Break from message parsing if whole message payload is not ready
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Fixes the bug when we try to read message payload without checking if we
received enough bytes or file descriptors.
2025-04-07 20:26:01 +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
R-Goc
28d5d982ce Everywhere: Remove unused private fields
Some checks are pending
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This commit removes the -Wno-unusued-private-field flag, thus
reenabling the warning. Unused field were either removed or marked
[[maybe_unused]] when unsure.
2025-04-04 12:40:07 +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
stasoid
2abc792938 LibCore: Implement System::set_close_on_exec 2025-03-19 20:25:24 -06: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
68947d55d9 LibIPC: Do not require constructing containers when sending IPC messages
For example, consider the following IPC message:

    do_something(u64 page_id, String string, Vector<Data> data) =|

We would previously generate the following C++ method to encode/transfer
this message:

    void do_something(u64 page_id, String string, Vector<Data> data);

This required the caller to either have to copy the non-trivial types or
`move` them in. In some places, this meant we had to construct temporary
vectors just to send an IPC.

This isn't necessary because we weren't holding onto these parameters
anyways. We would construct an IPC::Message subclass with them (which
does require owning types), but then immediate encode the message to
an IPC::MessageBuffer and send it.

We now generate code such that we don't need to construct a Message. We
can simply encode the parameters directly without needing ownership.
This allows us to take view-types to IPC parameters.

So the above example now becomes:

    void do_something(u64, StringView, ReadonlySpan<Data>);
2025-03-09 11:14:20 -04:00
Timothy Flynn
a5b996c079 LibIPC: Add a generic encoder for spans 2025-03-09 11:14:20 -04:00
Timothy Flynn
b090952274 LibIPC: Remove outdated warning about changing IPC encodings
We are no longer constrained by this LibC encoding.
2025-03-09 11:14:20 -04:00
Timothy Flynn
fe2dff4944 AK+Everywhere: Convert JSON value serialization to String
This removes the use of StringBuilder::OutputType (which was ByteString,
and only used by the JSON classes). And it removes the StringBuilder
template parameter from the serialization methods; this was only ever
used with StringBuilder, so a template is pretty overkill here.
2025-02-20 19:27:51 -05:00
Shannon Booth
25df98875d LibIPC: Ensure only valid URLs are passed over IPC
Invalid URLs should be signified by a wrapper class, such as an
Optional<URL::URL> in the IPC file. I do not believe that we have
anything which currently relies on passing through an invalid URL.
2025-02-19 08:01:35 -05:00
Sam Atkins
b3b7e76c10 IPCCompiler: Remove invalid state from IPC message classes
At some point, we stopped ever constructing invalid messages. This makes
that clearer, and will allow us to stop requiring that IPC arguments be
default-constructible.
2025-02-17 11:37:38 -05:00
Timothy Flynn
01044cbf1f LibIPC: Restore inline attribute on IPC constexpr booleans
These were mistakenly removed in commit d41e577ba.
2025-02-13 08:27:02 -05:00
stasoid
652af318db LibIPC: Port to Windows
The Linux IPC uses SCM_RIGHTS to transfer fds to another process
(see TransportSocket::transfer, which calls LocalSocket::send_message).
File descriptors are handled separately from regular data.

On Windows handles are embedded in regular data. They are duplicated
in the sender process.

Socket handles need special code both on sender side (because they
require using WSADuplicateSocket instead of DuplicateHandle, see
TransportSocketWindows::duplicate_handles) and on receiver side
(because they require WSASocket, see FileWindows.cpp).

TransportSocketWindows::ReadResult::fds vector is always empty, it is
kept the same as Linux version to avoid OS #ifdefs in Connection.h/.cpp
and Web::HTML::MessagePort::read_from_transport. Separate handling of
fds permeates all IPC code, it doesn't make sense to #ifdef out all this
code on Windows. In other words, the Linux code is more generic -
it handles both regular data and fds. On Windows, we need only the
regular data portion of it, and we just use that.

Duplicating handles on Windows requires pid of target (receiver)
process (see TransportSocketWindows::m_peer_pid). This pid is received
during special TransportSocketWindows initialization, which is performed
only on Windows. It is handled in a separate PR #3179.
Note: ChatGPT and [stackoverflow](https://stackoverflow.com/questions/25429887/getting-pid-of-peer-socket-on-windows) suggest using GetExtendedTcpTable/GetTcpTable2
to get peer pid, but this doesn't work because [MIB_TCPROW2::dwOwningPid](https://learn.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcprow2)
is "The PID of the process that issued a context bind for this TCP
connection.", so for both ends it will return the pid of the process
that called socketpair.

Co-Authored-By: Andrew Kaster <andrew@ladybird.org>
2025-02-12 22:31:43 -07:00
stasoid
d41e577ba1 LibIPC: Make Vector concept match AK::Vector with any inline_capacity
Also:
* Use SpecializationOf for Optional and Variant concepts
* Remove inline because it is implied by constexpr
* Reorder declarations from less to more specialized (in common sense)
2025-02-12 22:31:43 -07:00
Shannon Booth
ca3d9d9ee0 LibURL+LibWeb+LibIPC: Represent blob URL entry's object using structs
Instead of just putting in members directly, wrap them up in structs
which represent what a URL blob entry is meant to hold per the spec.
This makes more obvious what this is meant to represent, such as the
ByteBuffer being used to represent the bytes behind a Blob.

This also allows us to use a stronger type for a function that needs
to return a Blob URL entry's object.
2025-01-21 19:22:07 +00:00
Sam Atkins
2e64e0b836 LibURL: Migrate Origin scheme from ByteString to String 2024-11-30 12:07:39 +01:00
Sam Atkins
63688148b9 LibURL: Promote Host to a proper class
This lets us move a few Host-related functions (like serialization and
checks for what the Host is) into Host instead of having them dotted
around the codebase.

For now, the interface is still very Variant-like, to avoid having to
change quite so much in one go.
2024-11-30 12:07:39 +01:00
Sam Atkins
8b984c0c57 LibURL: Clarify whether an Origin is opaque
Origins are immutable and we know on construction whether an Origin is
opaque. This also removes an implicit reliance on Host's Empty state.
2024-11-30 12:07:39 +01:00
Andrew Kaster
0075048206 LibCore: Remove SessionManagement utilities
We don't need these, they are only relevant for SerenityOS system
builds of LibCore.
2024-11-26 11:00:48 +01:00
Andrew Kaster
1549d393b9 LibIPC: Remove socket path from IPC Client connections
We don't need these for Ladybird, and they are the only users of
some LibCore functions we can remove as well.
2024-11-26 11:00:48 +01:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Lenny Maiorani
e6f907a155 AK: Simplify constructors and conversions from nullptr_t
Problem:
- Many constructors are defined as `{}` rather than using the ` =
  default` compiler-provided constructor.
- Some types provide an implicit conversion operator from `nullptr_t`
  instead of requiring the caller to default construct. This violates
  the C++ Core Guidelines suggestion to declare single-argument
  constructors explicit
  (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c46-by-default-declare-single-argument-constructors-explicit).

Solution:
- Change default constructors to use the compiler-provided default
  constructor.
- Remove implicit conversion operators from `nullptr_t` and change
  usage to enforce type consistency without conversion.
2021-01-12 09:11:45 +01:00
AnotherTest
bdd4b99d72 LibIPC: Add an on_destruction hook to IPC::Message
Any cleanup of resources needed (up until the message is sent) can be
done here.
Currently, the only such resource is an IPC::File.
2020-12-30 20:37:41 +01:00
Lenny Maiorani
765936ebae
Everywhere: Switch from (void) to [[maybe_unused]] (#4473)
Problem:
- `(void)` simply casts the expression to void. This is understood to
  indicate that it is ignored, but this is really a compiler trick to
  get the compiler to not generate a warning.

Solution:
- Use the `[[maybe_unused]]` attribute to indicate the value is unused.

Note:
- Functions taking a `(void)` argument list have also been changed to
  `()` because this is not needed and shows up in the same grep
  command.
2020-12-21 00:09:48 +01:00
Andreas Kling
0e4ecca336 LibIPC: Remove use of ByteBuffer::wrap()
ByteBuffer::wrap() was useful before we had Span. Let's see if we can't
get rid of some more ByteBuffer wrapping.
2020-12-19 11:30:02 +01:00
Linus Groh
41d042cc86 LibIPC: Fix 'unused private member' error when building with clang
This was breaking the Lagom build when using clang, as m_sockfd's only
use is behind an #ifdef __serenity__. (void) it elsewhere to fix that.
2020-11-25 20:00:23 +01:00
Sergey Bugaev
23dc3ff0c2 LibIPC: Support sending file descriptors :^)
It is now possible to use the special IPC::File type in message arguments. In
C++, the type is nothing more than a wrapper over a file descriptor. But when
serializing/deserializing IPC::File arguments, LibIPC will use the sendfd/recvfd
kernel APIs instead of sending the integer inline.

This makes it quite convenient to pass files over IPC, and will allow us to
significantly tighten sandboxes in the future :^)

Closes https://github.com/SerenityOS/serenity/issues/3643
2020-11-23 18:37:40 +01:00
Sergey Bugaev
fa2e3e2be4 LibIPC: Prepend each message with its size
This makes it much simpler to determine when we've read a complete message, and
will make it possible to integrate recvfd() in the future commit.
2020-11-23 18:37:40 +01:00
AnotherTest
c930e02624 LibIPC: Add support for passing around ByteBuffers and HashMap<K, V>
It should be noted that using a shared buffer should still be preferred
over passing a raw ByteBuffer over the wire.
2020-11-08 21:46:13 +01:00
Andreas Kling
9103471863 LibIPC: Handle partial messages
Since we're using byte streamed Unix sockets for the IPC protocols,
it's possible for the kernel to run out of socket buffer space with
a partial message near the end of the buffer.

Handle this situation in IPC::Connection by buffering the bytes of
what may be a partial message, and prepending them to the incoming
data next time we receive from the peer.

This fixes WindowServer asserting when a peer is spamming it hard.
2020-10-25 11:37:42 +01:00
AnotherTest
b42c6ea281 LibIPC: Make IPC::encode() and ::decode() fail at compiletime when used
This would previously fail at runtime, and it would have zero indication
of what exactly went wrong.
Also adds `AK::DependentFalse<Ts...>', which is a...dependent false.
2020-10-04 23:12:28 +02:00
Andreas Kling
6c9a3ecf42 LibIPC: Silence a warning when compiling with gcc -O0 2020-10-01 19:16:35 +02:00
asynts
c879ecf509 LibIPC: Use InputMemoryStream instead of BufferStream. 2020-09-21 09:37:49 +02:00
Tom
5ee29e8a26 LibIPC: Check if socket is still open before using socket descriptor
Writing to the socket may trigger a close of the socket descriptor
if a disconnect was detected. We need to check if it is still valid
when waiting for a response after attempting to send a synchronous
message.

Fixes #3515
2020-09-17 09:47:29 +02:00
Tom
d55e3c4642 LibIPC: Disable Notifier before closing socket
Because we're closing a file descriptor, we need to disable any
Notifier that is using it so that the EventLoop does not use invalid
file descriptors.

Fixes #3508
2020-09-16 17:50:43 +02:00