1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-09 09:34:57 +09:00

LibIPC: Avoid redundant copy of every tranferred IPC message

For every IPC message sent, we currently prepend the message size to the
IPC message buffer. This incurs the cost of copying the entire message
to its newly allocated position. Instead, reserve the bytes for the size
at the front of the buffer upon creation. Prevent dangerous access to
the buffer with specific public methods.
This commit is contained in:
Timothy Flynn 2024-01-02 20:27:29 -05:00 committed by Andreas Kling
parent f2db700ae7
commit 34160743dc
Notes: sideshowbarker 2024-07-16 20:31:50 +09:00
4 changed files with 48 additions and 14 deletions

View file

@ -37,20 +37,20 @@ public:
ErrorOr<void> extend_capacity(size_t capacity)
{
return m_buffer.data.try_ensure_capacity(m_buffer.data.size() + capacity);
TRY(m_buffer.extend_data_capacity(capacity));
return {};
}
ErrorOr<void> append(u8 const* values, size_t count)
{
TRY(extend_capacity(count));
m_buffer.data.unchecked_append(values, count);
TRY(m_buffer.append_data(values, count));
return {};
}
ErrorOr<void> append_file_descriptor(int fd)
{
auto auto_fd = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AutoCloseFileDescriptor(fd)));
return m_buffer.fds.try_append(move(auto_fd));
TRY(m_buffer.append_file_descriptor(fd));
return {};
}
ErrorOr<void> encode_size(size_t size);

View file

@ -13,7 +13,7 @@ namespace IPC {
class Decoder;
class Encoder;
class Message;
struct MessageBuffer;
class MessageBuffer;
class File;
class Stub;

View file

@ -13,20 +13,45 @@ namespace IPC {
using MessageSizeType = u32;
MessageBuffer::MessageBuffer()
{
m_data.resize(sizeof(MessageSizeType));
}
ErrorOr<void> MessageBuffer::extend_data_capacity(size_t capacity)
{
TRY(m_data.try_ensure_capacity(m_data.size() + capacity));
return {};
}
ErrorOr<void> MessageBuffer::append_data(u8 const* values, size_t count)
{
TRY(m_data.try_append(values, count));
return {};
}
ErrorOr<void> MessageBuffer::append_file_descriptor(int fd)
{
auto auto_fd = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AutoCloseFileDescriptor(fd)));
TRY(m_fds.try_append(move(auto_fd)));
return {};
}
ErrorOr<void> MessageBuffer::transfer_message(Core::LocalSocket& fd_passing_socket, Core::LocalSocket& data_socket)
{
Checked<MessageSizeType> checked_message_size { data.size() };
Checked<MessageSizeType> checked_message_size { m_data.size() };
checked_message_size -= sizeof(MessageSizeType);
if (checked_message_size.has_overflow())
return Error::from_string_literal("Message is too large for IPC encoding");
auto message_size = checked_message_size.value();
TRY(data.try_prepend(reinterpret_cast<u8 const*>(&message_size), sizeof(message_size)));
m_data.span().overwrite(0, reinterpret_cast<u8 const*>(&message_size), sizeof(message_size));
for (auto const& fd : fds)
for (auto const& fd : m_fds)
TRY(fd_passing_socket.send_fd(fd->value()));
ReadonlyBytes bytes_to_write { data.span() };
ReadonlyBytes bytes_to_write { m_data.span() };
size_t writes_done = 0;
while (!bytes_to_write.is_empty()) {
@ -59,7 +84,7 @@ ErrorOr<void> MessageBuffer::transfer_message(Core::LocalSocket& fd_passing_sock
}
if (writes_done > 1) {
dbgln("LibIPC::transfer_message FIXME Warning, needed {} writes needed to send message of size {}B, this is pretty bad, as it spins on the EventLoop", writes_done, data.size());
dbgln("LibIPC::transfer_message FIXME Warning, needed {} writes needed to send message of size {}B, this is pretty bad, as it spins on the EventLoop", writes_done, m_data.size());
}
return {};

View file

@ -35,11 +35,20 @@ private:
int m_fd;
};
struct MessageBuffer {
class MessageBuffer {
public:
MessageBuffer();
ErrorOr<void> extend_data_capacity(size_t capacity);
ErrorOr<void> append_data(u8 const* values, size_t count);
ErrorOr<void> append_file_descriptor(int fd);
ErrorOr<void> transfer_message(Core::LocalSocket& fd_passing_socket, Core::LocalSocket& data_socket);
Vector<u8, 1024> data;
Vector<NonnullRefPtr<AutoCloseFileDescriptor>, 1> fds;
private:
Vector<u8, 1024> m_data;
Vector<NonnullRefPtr<AutoCloseFileDescriptor>, 1> m_fds;
};
enum class ErrorCode : u32 {