Fix an invalid foreach loop over an unordered_map with deletion in WiiSockets

This commit is contained in:
galop1n 2014-06-27 12:26:11 -04:00 committed by lioncash
parent bd377b9580
commit 729758f2f9
2 changed files with 17 additions and 12 deletions

View file

@ -570,8 +570,9 @@ s32 WiiSockMan::NewSocket(s32 af, s32 type, s32 protocol)
s32 WiiSockMan::DeleteSocket(s32 s)
{
s32 ReturnValue = WiiSockets[s].CloseFd();
WiiSockets.erase(s);
auto socket_entry = WiiSockets.find(s);
s32 ReturnValue = socket_entry->second.CloseFd();
WiiSockets.erase(socket_entry);
return ReturnValue;
}
@ -583,20 +584,25 @@ void WiiSockMan::Update()
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_ZERO(&except_fds);
for (auto& entry : WiiSockets)
auto socket_iter = WiiSockets.begin();
auto end_socks = WiiSockets.end();
while (socket_iter != end_socks)
{
WiiSocket& sock = entry.second;
WiiSocket& sock = socket_iter->second;
if (sock.IsValid())
{
FD_SET(sock.fd, &read_fds);
FD_SET(sock.fd, &write_fds);
FD_SET(sock.fd, &except_fds);
nfds = std::max(nfds, sock.fd+1);
++socket_iter;
}
else
{
// Good time to clean up invalid sockets.
WiiSockets.erase(sock.fd);
socket_iter = WiiSockets.erase(socket_iter);
}
}
s32 ret = select(nfds, &read_fds, &write_fds, &except_fds, &t);

View file

@ -192,7 +192,7 @@ public:
};
class WiiSockMan
class WiiSockMan : public ::NonCopyable
{
public:
static s32 GetNetErrorCode(s32 ret, std::string caller, bool isRW);
@ -222,7 +222,8 @@ public:
template <typename T>
void DoSock(s32 sock, u32 CommandAddress, T type)
{
if (WiiSockets.find(sock) == WiiSockets.end())
auto socket_entry = WiiSockets.find(sock);
if (socket_entry == WiiSockets.end())
{
IPCCommandType ct = static_cast<IPCCommandType>(Memory::Read_U32(CommandAddress));
ERROR_LOG(WII_IPC_NET,
@ -232,15 +233,13 @@ public:
}
else
{
WiiSockets[sock].DoSock(CommandAddress, type);
socket_entry->second.DoSock(CommandAddress, type);
}
}
private:
WiiSockMan() {}; // Constructor? (the {} brackets) are needed here.
WiiSockMan(WiiSockMan const&); // Don't Implement
void operator=(WiiSockMan const&); // Don't implement
std::unordered_map<s32, WiiSocket> WiiSockets;
WiiSockMan() = default;
std::unordered_map<s32, WiiSocket> WiiSockets;
s32 errno_last;
};