summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibIPC/Connection.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-10-23 22:16:53 +0200
committerAndreas Kling <kling@serenityos.org>2021-10-24 01:01:01 +0200
commit8728d36dd05813de1c2f27a528bb8e9fb5ee2b2c (patch)
tree72404c0e9236ffef71e63ba8eb13a84e043ca2a9 /Userland/Libraries/LibIPC/Connection.cpp
parentf3c4a357ea142ea107384c3dcbfc8f5d3ebb1a51 (diff)
downloadserenity-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.cpp32
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;
+}
+
}