Turn the socket manager into a class

This commit is contained in:
Henrik Rydgård committed 2025-01-08 14:59:40 +01:00
1 parent 5026e92450
commit 155a9f9dbc
4 files changed
+70 -57

No files matched your search

+16 -14
View File
@@ -3,36 +3,38 @@
#include <mutex>
// We use this array from 1 and forward. It's probably not a good idea to return 0 as a socket.
InetSocket g_inetSockets[256];
SocketManager g_socketManager;
static std::mutex g_socketMutex; // TODO: Remove once the adhoc thread is gone
int AllocInetSocket() {
InetSocket *SocketManager::AllocSocket(int *index) {
std::lock_guard<std::mutex> guard(g_socketMutex);
for (int i = MIN_VALID_INET_SOCKET; i < ARRAY_SIZE(g_inetSockets); i++) {
if (g_inetSockets[i].state == SocketState::Unused) {
return i;
for (int i = MIN_VALID_INET_SOCKET; i < ARRAY_SIZE(inetSockets_); i++) {
if (inetSockets_[i].state == SocketState::Unused) {
*index = i;
return inetSockets_ + i;
}
}
_dbg_assert_(false);
ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD.");
*index = 0;
return 0;
}
bool GetInetSocket(int sock, InetSocket **inetSocket) {
bool SocketManager::GetInetSocket(int sock, InetSocket **inetSocket) {
std::lock_guard<std::mutex> guard(g_socketMutex);
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(g_inetSockets) || g_inetSockets[sock].state == SocketState::Unused) {
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) {
*inetSocket = nullptr;
return false;
}
*inetSocket = &g_inetSockets[sock];
*inetSocket = inetSockets_ + sock;
return true;
}
// Simplified mappers, only really useful in select/poll
SOCKET GetHostSocketFromInetSocket(int sock) {
SOCKET SocketManager::GetHostSocketFromInetSocket(int sock) {
std::lock_guard<std::mutex> guard(g_socketMutex);
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(g_inetSockets) || g_inetSockets[sock].state == SocketState::Unused) {
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) {
_dbg_assert_(false);
return -1;
}
@@ -40,11 +42,11 @@ SOCKET GetHostSocketFromInetSocket(int sock) {
// Map 0 to 0, special case.
return 0;
}
return g_inetSockets[sock].sock;
return inetSockets_[sock].sock;
}
void CloseAllSockets() {
for (auto &sock : g_inetSockets) {
void SocketManager::CloseAll() {
for (auto &sock : inetSockets_) {
if (sock.state != SocketState::Unused) {
closesocket(sock.sock);
}
+22 -12
View File
@@ -13,22 +13,32 @@ enum class SocketState {
struct InetSocket {
SOCKET sock; // native socket
SocketState state;
// NOTE: These are the PSP types for now
// NOTE: These are the PSP types. Can be converted to the host types if needed.
int domain;
int type;
int protocol;
// These are the host types for convenience.
int hostDomain;
int hostType;
int hostProtocol;
};
#define MIN_VALID_INET_SOCKET 61
#define VALID_INET_SOCKET_COUNT 256
class SocketManager {
public:
enum {
VALID_INET_SOCKET_COUNT = 256,
MIN_VALID_INET_SOCKET = 61,
};
extern InetSocket g_inetSockets[VALID_INET_SOCKET_COUNT];
InetSocket *AllocSocket(int *index);
bool GetInetSocket(int sock, InetSocket **inetSocket);
SOCKET GetHostSocketFromInetSocket(int sock);
void CloseAll();
int AllocInetSocket();
bool GetInetSocket(int sock, InetSocket **inetSocket);
SOCKET GetHostSocketFromInetSocket(int sock);
void CloseAllSockets();
// 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;
+1
View File
@@ -280,6 +280,7 @@ SceNetAdhocctlPeerInfo* findFriendByIP(uint32_t ip) {
return peer;
}
// fd is a host socket
int IsSocketReady(int fd, bool readfd, bool writefd, int* errorcode, int timeoutUS) {
fd_set readfds, writefds;
timeval tval;
+31 -31
View File
@@ -33,7 +33,7 @@ void __NetInetShutdown() {
}
netInetInited = false;
CloseAllSockets();
g_socketManager.CloseAll();
}
static int sceNetInetInit() {
@@ -123,7 +123,7 @@ static int sceNetInetGetpeername(int socket, u32 namePtr, u32 namelenPtr) {
}
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -157,7 +157,7 @@ static int sceNetInetGetsockname(int socket, u32 namePtr, u32 namelenPtr) {
}
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -205,9 +205,9 @@ int sceNetInetSelect(int nfds, u32 readfdsPtr, u32 writefdsPtr, u32 exceptfdsPtr
// Save the mapping during setup.
SOCKET hostSockets[256]{};
for (int i = MIN_VALID_INET_SOCKET; i < nfds; i++) {
for (int i = SocketManager::MIN_VALID_INET_SOCKET; i < nfds; i++) {
if (readfds && (NetInetFD_ISSET(i, readfds))) {
SOCKET sock = GetHostSocketFromInetSocket(i);
SOCKET sock = g_socketManager.GetHostSocketFromInetSocket(i);
hostSockets[i] = sock;
DEBUG_LOG(Log::sceNet, "Input Read FD #%i (host: %d)", i, sock);
if (rdcnt < FD_SETSIZE) {
@@ -216,7 +216,7 @@ int sceNetInetSelect(int nfds, u32 readfdsPtr, u32 writefdsPtr, u32 exceptfdsPtr
}
}
if (writefds && (NetInetFD_ISSET(i, writefds))) {
SOCKET sock = GetHostSocketFromInetSocket(i);
SOCKET sock = g_socketManager.GetHostSocketFromInetSocket(i);
hostSockets[i] = sock;
DEBUG_LOG(Log::sceNet, "Input Write FD #%i (host: %d)", i, sock);
if (wrcnt < FD_SETSIZE) {
@@ -225,7 +225,7 @@ int sceNetInetSelect(int nfds, u32 readfdsPtr, u32 writefdsPtr, u32 exceptfdsPtr
}
}
if (exceptfds && (NetInetFD_ISSET(i, exceptfds))) {
SOCKET sock = GetHostSocketFromInetSocket(i);
SOCKET sock = g_socketManager.GetHostSocketFromInetSocket(i);
hostSockets[i] = sock;
DEBUG_LOG(Log::sceNet, "Input Except FD #%i (host: %d)", i, sock);
if (excnt < FD_SETSIZE) {
@@ -254,7 +254,7 @@ int sceNetInetSelect(int nfds, u32 readfdsPtr, u32 writefdsPtr, u32 exceptfdsPtr
if (readfds != NULL) NetInetFD_ZERO(readfds);
if (writefds != NULL) NetInetFD_ZERO(writefds);
if (exceptfds != NULL) NetInetFD_ZERO(exceptfds);
for (int i = MIN_VALID_INET_SOCKET; i < nfds; i++) {
for (int i = SocketManager::MIN_VALID_INET_SOCKET; i < nfds; i++) {
if (readfds && hostSockets[i] != 0 && FD_ISSET(hostSockets[i], &rdfds)) {
NetInetFD_SET(i, readfds);
}
@@ -296,7 +296,7 @@ int sceNetInetPoll(u32 fdsPtr, u32 nfds, int timeout) { // timeout in milisecond
if (fdarray[i].fd > maxfd) {
maxfd = fdarray[i].fd;
}
SOCKET hostSocket = GetHostSocketFromInetSocket(fdarray[i].fd);
SOCKET hostSocket = g_socketManager.GetHostSocketFromInetSocket(fdarray[i].fd);
FD_SET(hostSocket, &readfds);
FD_SET(hostSocket, &writefds);
FD_SET(hostSocket, &exceptfds);
@@ -317,7 +317,7 @@ int sceNetInetPoll(u32 fdsPtr, u32 nfds, int timeout) { // timeout in milisecond
retval = 0;
for (int i = 0; i < (s32)nfds; i++) {
SOCKET hostSocket = GetHostSocketFromInetSocket(fdarray[i].fd);
SOCKET hostSocket = g_socketManager.GetHostSocketFromInetSocket(fdarray[i].fd);
if ((fdarray[i].events & (INET_POLLRDNORM | INET_POLLIN)) && FD_ISSET(hostSocket, &readfds))
fdarray[i].revents |= (INET_POLLRDNORM | INET_POLLIN); //POLLIN_SET
if ((fdarray[i].events & (INET_POLLWRNORM | INET_POLLOUT)) && FD_ISSET(hostSocket, &writefds))
@@ -337,7 +337,7 @@ static int sceNetInetRecv(int socket, u32 bufPtr, u32 bufLen, u32 flags) {
DEBUG_LOG(Log::sceNet, "UNTESTED sceNetInetRecv(%i, %08x, %i, %08x) at %08x", socket, bufPtr, bufLen, flags, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -364,7 +364,7 @@ static int sceNetInetSend(int socket, u32 bufPtr, u32 bufLen, u32 flags) {
DEBUG_LOG(Log::sceNet, "UNTESTED sceNetInetSend(%i, %08x, %i, %08x) at %08x", socket, bufPtr, bufLen, flags, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -404,20 +404,19 @@ static int sceNetInetSocket(int domain, int type, int protocol) {
// Register the socket.
int socket = AllocInetSocket();
int socket;
InetSocket *inetSock = g_socketManager.AllocSocket(&socket);
if (socket < 0) {
// Alloc already logged. Let's bail.
return hleLogError(Log::sceNet, ERROR_NET_INTERNAL);
}
InetSocket *inetSock = &g_inetSockets[socket];
inetSock->state = SocketState::UsedNetInet;
inetSock->sock = hostSock;
inetSock->domain = domain;
inetSock->type = type;
inetSock->protocol = protocol;
inetSock->hostDomain = hostDomain;
inetSock->hostType = hostType;
inetSock->hostProtocol = hostProtocol;
// Ignore SIGPIPE when supported (ie. BSD/MacOS)
setSockNoSIGPIPE(hostSock, 1);
@@ -427,6 +426,7 @@ static int sceNetInetSocket(int domain, int type, int protocol) {
setSockReuseAddrPort(hostSock);
// Disable Connection Reset error on UDP to avoid strange behavior
setUDPConnReset(hostSock, false);
return hleLogSuccessI(Log::sceNet, socket);
}
@@ -434,7 +434,7 @@ static int sceNetInetSetsockopt(int socket, int level, int optname, u32 optvalPt
WARN_LOG(Log::sceNet, "UNTESTED %s(%i, %i, %i, %08x, %i) at %08x", __FUNCTION__, socket, level, optname, optvalPtr, optlen, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -495,7 +495,7 @@ static int sceNetInetGetsockopt(int socket, int level, int optname, u32 optvalPt
WARN_LOG(Log::sceNet, "UNTESTED %s(%i, %i, %i, %08x, %08x) at %08x", __FUNCTION__, socket, level, optname, optvalPtr, optlenPtr, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -560,7 +560,7 @@ static int sceNetInetBind(int socket, u32 namePtr, int namelen) {
WARN_LOG(Log::sceNet, "UNTESTED %s(%i, %08x, %i) at %08x", __FUNCTION__, socket, namePtr, namelen, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -614,7 +614,7 @@ static int sceNetInetConnect(int socket, u32 sockAddrPtr, int sockAddrLen) {
WARN_LOG(Log::sceNet, "UNTESTED %s(%i, %08x, %i) at %08x", __FUNCTION__, socket, sockAddrPtr, sockAddrLen, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -652,7 +652,7 @@ static int sceNetInetListen(int socket, int backlog) {
WARN_LOG(Log::sceNet, "UNTESTED %s(%i, %i) at %08x", __FUNCTION__, socket, backlog, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -669,7 +669,7 @@ static int sceNetInetAccept(int socket, u32 addrPtr, u32 addrLenPtr) {
WARN_LOG(Log::sceNet, "UNTESTED %s(%i, %08x, %08x) at %08x", __FUNCTION__, socket, addrPtr, addrLenPtr, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -702,7 +702,7 @@ static int sceNetInetShutdown(int socket, int how) {
WARN_LOG(Log::sceNet, "UNTESTED %s(%i, %i) at %08x", __FUNCTION__, socket, how, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -722,7 +722,7 @@ static int sceNetInetSocketAbort(int socket) {
WARN_LOG(Log::sceNet, "UNTESTED %s(%i)", __FUNCTION__, socket);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -735,7 +735,7 @@ static int sceNetInetClose(int socket) {
WARN_LOG(Log::sceNet, "UNTESTED %s(%i) at %08x", __FUNCTION__, socket, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -754,7 +754,7 @@ static int sceNetInetCloseWithRST(int socket) {
WARN_LOG(Log::sceNet, "UNTESTED %s(%i) at %08x", __FUNCTION__, socket, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -777,7 +777,7 @@ static int sceNetInetRecvfrom(int socket, u32 bufferPtr, int len, int flags, u32
DEBUG_LOG(Log::sceNet, "UNTESTED %s(%i, %08x, %i, %08x, %08x, %08x) at %08x", __FUNCTION__, socket, bufferPtr, len, flags, fromPtr, fromlenPtr, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -825,7 +825,7 @@ static int sceNetInetSendto(int socket, u32 bufferPtr, int len, int flags, u32 t
DEBUG_LOG(Log::sceNet, "UNTESTED %s(%i, %08x, %i, %08x, %08x, %d) at %08x", __FUNCTION__, socket, bufferPtr, len, flags, toPtr, tolen, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -909,7 +909,7 @@ static int sceNetInetSendmsg(int socket, u32 msghdrPtr, int flags) {
}
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}
@@ -1103,7 +1103,7 @@ static int sceNetInetRecvmsg(int socket, u32 msghdrPtr, int flags) {
ERROR_LOG(Log::sceNet, "UNIMPL %s(%i, %08x, %08x) at %08x", __FUNCTION__, socket, msghdrPtr, flags, currentMIPS->pc);
InetSocket *inetSock;
if (!GetInetSocket(socket, &inetSock)) {
if (!g_socketManager.GetInetSocket(socket, &inetSock)) {
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
}