From 8728d36dd05813de1c2f27a528bb8e9fb5ee2b2c Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 23 Oct 2021 22:16:53 +0200 Subject: 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. --- Userland/Libraries/LibIPC/Connection.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'Userland/Libraries/LibIPC/Connection.cpp') 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, 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(*this)); + return false; + } + if (!m_unprocessed_bytes.is_empty()) { + dbgln("{}::drain_messages_from_peer: Already have unprocessed bytes", static_cast(*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; +} + } -- cgit v1.2.3