diff options
author | Andreas Kling <kling@serenityos.org> | 2021-10-23 22:16:53 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-10-24 01:01:01 +0200 |
commit | 8728d36dd05813de1c2f27a528bb8e9fb5ee2b2c (patch) | |
tree | 72404c0e9236ffef71e63ba8eb13a84e043ca2a9 /Userland/Libraries/LibIPC/Connection.cpp | |
parent | f3c4a357ea142ea107384c3dcbfc8f5d3ebb1a51 (diff) | |
download | serenity-8728d36dd05813de1c2f27a528bb8e9fb5ee2b2c.zip |
LibIPC: Move more of IPC::Connection to ConnectionBase
This patch moves the templated message parsing code to a virtual
try_parse_messages() helper. By doing that, we can move the rest of the
socket draining code up to ConnectionBase and keep it out of line.
Diffstat (limited to 'Userland/Libraries/LibIPC/Connection.cpp')
-rw-r--r-- | Userland/Libraries/LibIPC/Connection.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/Userland/Libraries/LibIPC/Connection.cpp b/Userland/Libraries/LibIPC/Connection.cpp index 91b24a2553..4d2c29ea80 100644 --- a/Userland/Libraries/LibIPC/Connection.cpp +++ b/Userland/Libraries/LibIPC/Connection.cpp @@ -149,4 +149,36 @@ Result<Vector<u8>, bool> ConnectionBase::read_as_much_as_possible_from_socket_wi return bytes; } +bool ConnectionBase::drain_messages_from_peer(u32 local_endpoint_magic) +{ + auto bytes = TRY(read_as_much_as_possible_from_socket_without_blocking()); + + size_t index = 0; + try_parse_messages(bytes, index); + + if (index < bytes.size()) { + // Sometimes we might receive a partial message. That's okay, just stash away + // the unprocessed bytes and we'll prepend them to the next incoming message + // in the next run of this function. + auto remaining_bytes_result = ByteBuffer::copy(bytes.span().slice(index)); + if (!remaining_bytes_result.has_value()) { + dbgln("{}::drain_messages_from_peer: Failed to allocate buffer", static_cast<Core::Object const&>(*this)); + return false; + } + if (!m_unprocessed_bytes.is_empty()) { + dbgln("{}::drain_messages_from_peer: Already have unprocessed bytes", static_cast<Core::Object const&>(*this)); + shutdown(); + return false; + } + m_unprocessed_bytes = remaining_bytes_result.release_value(); + } + + if (!m_unprocessed_messages.is_empty()) { + deferred_invoke([this, local_endpoint_magic] { + handle_messages(local_endpoint_magic); + }); + } + return true; +} + } |