Skip to content

Commit

Permalink
DEV9: Defer deletion of socket sessions
Browse files Browse the repository at this point in the history
  • Loading branch information
TheLastRar authored and stenzek committed May 4, 2024
1 parent ce734f8 commit 8bfcbde
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
46 changes: 40 additions & 6 deletions pcsx2/DEV9/sockets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "common/Assertions.h"
#include "common/StringUtil.h"
#include "common/ScopedGuard.h"

#ifdef _WIN32
#include <winsock2.h>
Expand Down Expand Up @@ -216,6 +217,8 @@ SocketAdapter::SocketAdapter()
wsa_init = true;
#endif

sendThreadId = std::this_thread::get_id();

initialized = true;
}

Expand All @@ -234,6 +237,13 @@ bool SocketAdapter::recv(NetPacket* pkt)
if (NetAdapter::recv(pkt))
return true;

ScopedGuard cleanup([&]() {
// Garbage collect closed connections
for (BaseSession* s : deleteQueueRecvThread)
delete s;
deleteQueueRecvThread.clear();
});

EthernetFrame* bFrame;
if (!vRecBuffer.Dequeue(&bFrame))
{
Expand Down Expand Up @@ -282,6 +292,14 @@ bool SocketAdapter::send(NetPacket* pkt)
if (NetAdapter::send(pkt))
return true;

pxAssert(std::this_thread::get_id() == sendThreadId);
ScopedGuard cleanup([&]() {
// Garbage collect closed connections
for (BaseSession* s : deleteQueueSendThread)
delete s;
deleteQueueSendThread.clear();
});

EthernetFrame frame(pkt);

switch (frame.protocol)
Expand Down Expand Up @@ -548,9 +566,12 @@ void SocketAdapter::HandleConnectionClosed(BaseSession* sender)
{
const ConnectionKey key = sender->key;
connections.Remove(key);
//Note, we delete something that is calling us
//this is probably going to cause issues
delete sender;

// Defer deleting the connection untill we have left the calling session's callstack
if (std::this_thread::get_id() == sendThreadId)
deleteQueueSendThread.push_back(sender);
else
deleteQueueRecvThread.push_back(sender);

switch (key.protocol)
{
Expand All @@ -577,9 +598,12 @@ void SocketAdapter::HandleFixedPortClosed(BaseSession* sender)
ConnectionKey key = sender->key;
connections.Remove(key);
fixedUDPPorts.Remove(key.ps2Port);
//Note, we delete something that is calling us
//this is probably going to cause issues
delete sender;

// Defer deleting the connection untill we have left the calling session's callstack
if (std::this_thread::get_id() == sendThreadId)
deleteQueueSendThread.push_back(sender);
else
deleteQueueRecvThread.push_back(sender);

Console.WriteLn("DEV9: Socket: Closed Dead UDP Fixed Port to %d", key.ps2Port);
}
Expand All @@ -604,6 +628,16 @@ SocketAdapter::~SocketAdapter()
connections.Clear();
fixedUDPPorts.Clear(); //fixedUDP sessions already deleted via connections

//Clear out any delete queues
DevCon.WriteLn("DEV9: Socket: Found %d Connections in send delete queue", deleteQueueSendThread.size());
DevCon.WriteLn("DEV9: Socket: Found %d Connections in recv delete queue", deleteQueueRecvThread.size());
for (BaseSession* s : deleteQueueSendThread)
delete s;
for (BaseSession* s : deleteQueueRecvThread)
delete s;
deleteQueueSendThread.clear();
deleteQueueRecvThread.clear();

//Clear out vRecBuffer
while (!vRecBuffer.IsQueueEmpty())
{
Expand Down
4 changes: 4 additions & 0 deletions pcsx2/DEV9/sockets.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class SocketAdapter : public NetAdapter
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;

public:
SocketAdapter();
virtual bool blocks();
Expand Down

0 comments on commit 8bfcbde

Please sign in to comment.