DEV9: Fix race condition when handling closed socket connections

This commit is contained in:
TheLastRar 2025-04-12 16:32:50 +01:00
parent e4eea70ac0
commit 76746a0cb2
2 changed files with 22 additions and 8 deletions

View File

@ -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<ConnectionKey> 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:

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include <mutex>
#include <vector>
#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<Sessions::ConnectionKey, Sessions::BaseSession*> connections;
ThreadSafeMap<u16, Sessions::BaseSession*> fixedUDPPorts;
std::thread::id sendThreadId;
std::vector<Sessions::BaseSession*> deleteQueueSendThread;
std::vector<Sessions::BaseSession*> 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();