From 76746a0cb25cb7e001ba87b34d5a00b9ba683e7a Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Sat, 12 Apr 2025 16:32:50 +0100 Subject: [PATCH] DEV9: Fix race condition when handling closed socket connections --- pcsx2/DEV9/sockets.cpp | 22 ++++++++++++++++------ pcsx2/DEV9/sockets.h | 8 ++++++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/pcsx2/DEV9/sockets.cpp b/pcsx2/DEV9/sockets.cpp index 745de87d10..667944118c 100644 --- a/pcsx2/DEV9/sockets.cpp +++ b/pcsx2/DEV9/sockets.cpp @@ -203,14 +203,19 @@ bool SocketAdapter::recv(NetPacket* pkt) ScopedGuard cleanup([&]() { // Garbage collect closed connections - for (BaseSession* s : deleteQueueRecvThread) - delete s; - deleteQueueRecvThread.clear(); + if (deleteQueueRecvThread.size() != 0) + { + std::lock_guard deletelock(deleteRecvSentry); + for (BaseSession* s : deleteQueueRecvThread) + delete s; + deleteQueueRecvThread.clear(); + } }); EthernetFrame* bFrame; if (!vRecBuffer.Dequeue(&bFrame)) { + std::lock_guard deletelock(deleteSendSentry); std::vector keys = connections.GetKeys(); for (size_t i = 0; i < keys.size(); i++) { @@ -259,9 +264,13 @@ bool SocketAdapter::send(NetPacket* pkt) pxAssert(std::this_thread::get_id() == sendThreadId); ScopedGuard cleanup([&]() { // Garbage collect closed connections - for (BaseSession* s : deleteQueueSendThread) - delete s; - deleteQueueSendThread.clear(); + if (deleteQueueSendThread.size() != 0) + { + std::lock_guard deletelock(deleteSendSentry); + for (BaseSession* s : deleteQueueSendThread) + delete s; + deleteQueueSendThread.clear(); + } }); EthernetFrame frame(pkt); @@ -375,6 +384,7 @@ bool SocketAdapter::SendIP(IP_Packet* ipPkt) Key.ip = ipPkt->destinationIP; Key.protocol = ipPkt->protocol; + std::lock_guard deletelock(deleteRecvSentry); switch (ipPkt->protocol) //(Prase Payload) { case (u8)IP_Type::ICMP: diff --git a/pcsx2/DEV9/sockets.h b/pcsx2/DEV9/sockets.h index ae970e80ad..b5b9dd538b 100644 --- a/pcsx2/DEV9/sockets.h +++ b/pcsx2/DEV9/sockets.h @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0+ #pragma once +#include #include #include "net.h" @@ -23,14 +24,17 @@ class SocketAdapter : public NetAdapter bool initialized = false; PacketReader::IP::IP_Address adapterIP; - //Sentrys replaced by the requirment for each session class to have thread safe destructor - ThreadSafeMap connections; ThreadSafeMap fixedUDPPorts; std::thread::id sendThreadId; std::vector deleteQueueSendThread; std::vector deleteQueueRecvThread; + //Mutex to be held when processing the delete queue. + //The Send thread will lock the RecvSentry to prevent the recv thread + //from deleting a session the send thread might be currently working on. + std::mutex deleteSendSentry; + std::mutex deleteRecvSentry; public: SocketAdapter();