Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #536 from lioncash/WiiSocketBugFix
Fix an invalid foreach loop over an unordered_map with deletion inside WiiSockets
  • Loading branch information
lioncash committed Jun 27, 2014
2 parents bd377b9 + 729758f commit 10e746a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 12 deletions.
16 changes: 11 additions & 5 deletions Source/Core/Core/IPC_HLE/WII_Socket.cpp
Expand Up @@ -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;
}

Expand All @@ -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);
Expand Down
13 changes: 6 additions & 7 deletions Source/Core/Core/IPC_HLE/WII_Socket.h
Expand Up @@ -192,7 +192,7 @@ class WiiSocket

};

class WiiSockMan
class WiiSockMan : public ::NonCopyable
{
public:
static s32 GetNetErrorCode(s32 ret, std::string caller, bool isRW);
Expand Down Expand Up @@ -222,7 +222,8 @@ class WiiSockMan
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,
Expand All @@ -232,15 +233,13 @@ class WiiSockMan
}
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;
};

0 comments on commit 10e746a

Please sign in to comment.