forked from hrydgard/ppsspp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request hrydgard#19827 from hrydgard/net-inet-socket-remap
sceNetInet socket remap
- Loading branch information
Showing
14 changed files
with
538 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#include "Common/Net/SocketCompat.h" | ||
#include "Core/HLE/NetInetConstants.h" | ||
#include "Core/HLE/SocketManager.h" | ||
#include "Common/Log.h" | ||
|
||
#include <mutex> | ||
|
||
SocketManager g_socketManager; | ||
static std::mutex g_socketMutex; // TODO: Remove once the adhoc thread is gone | ||
|
||
InetSocket *SocketManager::CreateSocket(int *index, int *returned_errno, SocketState state, int domain, int type, int protocol) { | ||
_dbg_assert_(state != SocketState::Unused); | ||
|
||
int hostDomain = convertSocketDomainPSP2Host(domain); | ||
int hostType = convertSocketTypePSP2Host(type); | ||
int hostProtocol = convertSocketProtoPSP2Host(protocol); | ||
|
||
SOCKET hostSock = ::socket(hostDomain, hostType, hostProtocol); | ||
if (hostSock < 0) { | ||
*returned_errno = socket_errno; | ||
return nullptr; | ||
} | ||
|
||
std::lock_guard<std::mutex> guard(g_socketMutex); | ||
|
||
for (int i = MIN_VALID_INET_SOCKET; i < ARRAY_SIZE(inetSockets_); i++) { | ||
if (inetSockets_[i].state == SocketState::Unused) { | ||
*index = i; | ||
InetSocket *inetSock = inetSockets_ + i; | ||
inetSock->sock = hostSock; | ||
inetSock->state = state; | ||
inetSock->domain = domain; | ||
inetSock->type = type; | ||
inetSock->protocol = protocol; | ||
inetSock->nonblocking = false; | ||
*returned_errno = 0; | ||
return inetSock; | ||
} | ||
} | ||
_dbg_assert_(false); | ||
|
||
ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD."); | ||
closesocket(hostSock); | ||
*index = 0; | ||
*returned_errno = ENOMEM; // or something.. | ||
return nullptr; | ||
} | ||
|
||
bool SocketManager::Close(InetSocket *inetSocket) { | ||
_dbg_assert_(inetSocket->state != SocketState::Unused); | ||
if (closesocket(inetSocket->sock) != 0) { | ||
ERROR_LOG(Log::sceNet, "closesocket(%d) failed", inetSocket->sock); | ||
return false; | ||
} | ||
inetSocket->state = SocketState::Unused; | ||
inetSocket->sock = 0; | ||
return true; | ||
} | ||
|
||
bool SocketManager::GetInetSocket(int sock, InetSocket **inetSocket) { | ||
std::lock_guard<std::mutex> guard(g_socketMutex); | ||
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) { | ||
*inetSocket = nullptr; | ||
return false; | ||
} | ||
*inetSocket = inetSockets_ + sock; | ||
return true; | ||
} | ||
|
||
// Simplified mappers, only really useful in select/poll | ||
SOCKET SocketManager::GetHostSocketFromInetSocket(int sock) { | ||
std::lock_guard<std::mutex> guard(g_socketMutex); | ||
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) { | ||
_dbg_assert_(false); | ||
return -1; | ||
} | ||
if (sock == 0) { | ||
// Map 0 to 0, special case. | ||
return 0; | ||
} | ||
return inetSockets_[sock].sock; | ||
} | ||
|
||
void SocketManager::CloseAll() { | ||
for (auto &sock : inetSockets_) { | ||
if (sock.state != SocketState::Unused) { | ||
closesocket(sock.sock); | ||
} | ||
sock.state = SocketState::Unused; | ||
sock.sock = 0; | ||
} | ||
} | ||
|
||
const char *SocketStateToString(SocketState state) { | ||
switch (state) { | ||
case SocketState::Unused: return "unused"; | ||
case SocketState::UsedNetInet: return "netInet"; | ||
case SocketState::UsedProAdhoc: return "proAdhoc"; | ||
default: | ||
return "N/A"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#pragma once | ||
|
||
#include "Common/Net/SocketCompat.h" | ||
|
||
// Keep track of who's using a socket. | ||
enum class SocketState { | ||
Unused = 0, | ||
UsedNetInet, | ||
UsedProAdhoc, | ||
}; | ||
|
||
const char *SocketStateToString(SocketState state); | ||
|
||
// Internal socket state tracking | ||
struct InetSocket { | ||
SOCKET sock; // native socket | ||
SocketState state; | ||
// NOTE: These are the PSP types. Can be converted to the host types if needed. | ||
int domain; | ||
int type; | ||
int protocol; | ||
bool nonblocking; | ||
}; | ||
|
||
// Only use this for sockets whose ID are exposed to the game. | ||
// Don't really need to bother with the others, as the game doesn't know about them. | ||
class SocketManager { | ||
public: | ||
enum { | ||
VALID_INET_SOCKET_COUNT = 256, | ||
MIN_VALID_INET_SOCKET = 1, | ||
}; | ||
|
||
InetSocket *CreateSocket(int *index, int *returned_errno, SocketState state, int domain, int type, int protocol); | ||
bool GetInetSocket(int sock, InetSocket **inetSocket); | ||
SOCKET GetHostSocketFromInetSocket(int sock); | ||
bool Close(InetSocket *inetSocket); | ||
void CloseAll(); | ||
|
||
// For debugger | ||
const InetSocket *Sockets() { | ||
return inetSockets_; | ||
} | ||
|
||
private: | ||
// We use this array from MIN_VALID_INET_SOCKET and forward. It's probably not a good idea to return 0 as a socket. | ||
InetSocket inetSockets_[VALID_INET_SOCKET_COUNT]; | ||
}; | ||
|
||
extern SocketManager g_socketManager; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.