diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-11-03 00:28:31 +0100 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-11-03 00:28:31 +0100 |
| commit | 3e29ad38277195a2930b6ae89dba6d3e698c17e2 (patch) | |
| tree | 209cc84b76e98c1eaa29d8540cdf9eb1f5f4dfd5 /src/core/internal_network/socket_proxy.cpp | |
| parent | 78e0a12180a71adf8dffc2c2f6697a0a0735d5ea (diff) | |
network: use the socket type for room stream reads and wake all readers
socket(AF_INET, SOCK_STREAM, 0) leaves the protocol unspecified, so the
TCP checks in ProxySocket::Recv and ReceivePacket missed such sockets.
recv() then waited for the timeout and returned EAGAIN instead of end of
stream, and partial reads dropped the rest of the packet. Keep the socket
type and use it for these checks. The protocol stays as it is, because it
is sent to other room members.
A MSG_PEEK reader leaves the packet queued, so notify every waiter when a
packet arrives instead of only one.
Assisted-by: Claude Opus 5.5 (investigation and implementation)
Diffstat (limited to 'src/core/internal_network/socket_proxy.cpp')
| -rw-r--r-- | src/core/internal_network/socket_proxy.cpp | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/src/core/internal_network/socket_proxy.cpp b/src/core/internal_network/socket_proxy.cpp index 6c2f79da6e..1b93ce93e5 100644 --- a/src/core/internal_network/socket_proxy.cpp +++ b/src/core/internal_network/socket_proxy.cpp @@ -60,7 +60,8 @@ void ProxySocket::HandleProxyPacket(const ProxyPacket& packet) { } received_packets.push(std::move(decompressed)); } - packets_cv.notify_one(); + // A MSG_PEEK reader leaves the packet queued, so every waiter must see it + packets_cv.notify_all(); } template <typename T> @@ -72,6 +73,7 @@ Errno ProxySocket::SetSockOpt(SOCKET fd_, int option, T value) { Errno ProxySocket::Initialize(Domain domain, Type type, Protocol socket_protocol) { { std::lock_guard guard(packets_mutex); + socket_type = type; protocol = socket_protocol; } SetSockOpt(fd, SO_TYPE, type); @@ -122,7 +124,7 @@ Errno ProxySocket::Shutdown(ShutdownHow how) { } std::pair<s32, Errno> ProxySocket::Recv(int flags, std::span<u8> message) { - if (protocol == Protocol::TCP) { + if (socket_type == Type::STREAM) { // Room TCP sockets have no peer (Connect and Send are stubs). Report an empty queue as the // end of the stream, as before, instead of blocking the bsd service until the timeout. std::lock_guard guard(packets_mutex); @@ -179,7 +181,7 @@ std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> messag return {static_cast<s32>(read_bytes), Errno::SUCCESS}; } - if (protocol == Protocol::TCP && read_bytes < unread.size()) { + if (socket_type == Type::STREAM && read_bytes < unread.size()) { // Keep the unread part of the stream for the next call front_read_offset += read_bytes; } else { |
