aboutsummaryrefslogtreecommitdiff
path: root/src/core/internal_network/socket_proxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/internal_network/socket_proxy.cpp')
-rw-r--r--src/core/internal_network/socket_proxy.cpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/src/core/internal_network/socket_proxy.cpp b/src/core/internal_network/socket_proxy.cpp
index 83eb2ce9d0..6c2f79da6e 100644
--- a/src/core/internal_network/socket_proxy.cpp
+++ b/src/core/internal_network/socket_proxy.cpp
@@ -43,9 +43,21 @@ void ProxySocket::HandleProxyPacket(const ProxyPacket& packet) {
LOG_INFO(Network, "Received broadcast packet, but not configured for broadcast mode");
return;
}
+ }
- auto decompressed = packet;
- decompressed.data = Common::Compression::DecompressDataZSTD(packet.data);
+ // Decompress without the lock, so the game thread does not wait for it
+ ProxyPacket decompressed{
+ .local_endpoint = packet.local_endpoint,
+ .remote_endpoint = packet.remote_endpoint,
+ .protocol = packet.protocol,
+ .broadcast = packet.broadcast,
+ .data = Common::Compression::DecompressDataZSTD(packet.data),
+ };
+ {
+ std::lock_guard guard(packets_mutex);
+ if (closed) {
+ return;
+ }
received_packets.push(std::move(decompressed));
}
packets_cv.notify_one();
@@ -152,26 +164,28 @@ std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::span<u8> message, So
std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> message, SockAddrIn* addr,
std::size_t max_length) {
- ProxyPacket& packet = received_packets.front();
+ const ProxyPacket& packet = received_packets.front();
if (addr) {
addr->family = Domain::INET;
addr->ip = packet.local_endpoint.ip; // The senders ip address
addr->portno = packet.local_endpoint.portno; // The senders port number
}
- const std::size_t read_bytes = (std::min)(packet.data.size(), max_length);
- std::memcpy(message.data(), packet.data.data(), read_bytes);
+ const std::span<const u8> unread = std::span{packet.data}.subspan(front_read_offset);
+ const std::size_t read_bytes = (std::min)(unread.size(), max_length);
+ std::memcpy(message.data(), unread.data(), read_bytes);
if ((flags & FLAG_MSG_PEEK) != 0) {
return {static_cast<s32>(read_bytes), Errno::SUCCESS};
}
- if (protocol == Protocol::TCP && read_bytes < packet.data.size()) {
+ if (protocol == Protocol::TCP && read_bytes < unread.size()) {
// Keep the unread part of the stream for the next call
- packet.data.erase(packet.data.begin(), packet.data.begin() + read_bytes);
+ front_read_offset += read_bytes;
} else {
// Like BSD recv(), the rest of a datagram that does not fit is discarded
received_packets.pop();
+ front_read_offset = 0;
}
return {static_cast<s32>(read_bytes), Errno::SUCCESS};
@@ -240,6 +254,7 @@ Errno ProxySocket::Close() {
fd = INVALID_SOCKET;
closed = true;
received_packets = {};
+ front_read_offset = 0;
}
packets_cv.notify_all();