From a1744a6989a5afed1a9480aa43fbaf150f4c6ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 8 Jan 2025 15:27:54 +0100 Subject: [PATCH] Add SocketManager::CreateSocket for convenience --- Core/HLE/SocketManager.cpp | 27 ++++++++++++++++++++++++--- Core/HLE/SocketManager.h | 2 +- Core/HLE/sceNetInet.cpp | 35 ++++++++--------------------------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/Core/HLE/SocketManager.cpp b/Core/HLE/SocketManager.cpp index 03f8c0ee5c..e740db5c62 100644 --- a/Core/HLE/SocketManager.cpp +++ b/Core/HLE/SocketManager.cpp @@ -1,3 +1,5 @@ +#include "Common/Net/SocketCompat.h" +#include "Core/HLE/NetInetConstants.h" #include "Core/HLE/SocketManager.h" #include "Common/Log.h" @@ -6,19 +8,38 @@ SocketManager g_socketManager; static std::mutex g_socketMutex; // TODO: Remove once the adhoc thread is gone -InetSocket *SocketManager::AllocSocket(int *index) { +InetSocket *SocketManager::CreateSocket(int *index, 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) { + return nullptr; + } + std::lock_guard guard(g_socketMutex); + for (int i = MIN_VALID_INET_SOCKET; i < ARRAY_SIZE(inetSockets_); i++) { if (inetSockets_[i].state == SocketState::Unused) { *index = i; - return inetSockets_ + i; + InetSocket *inetSock = inetSockets_ + i; + inetSock->sock = hostSock; + inetSock->state = state; + inetSock->domain = domain; + inetSock->type = type; + inetSock->protocol = protocol; + return inetSock; } } _dbg_assert_(false); ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD."); + closesocket(hostSock); *index = 0; - return 0; + return nullptr; } bool SocketManager::GetInetSocket(int sock, InetSocket **inetSocket) { diff --git a/Core/HLE/SocketManager.h b/Core/HLE/SocketManager.h index 2a5ee61fe0..888764ed79 100644 --- a/Core/HLE/SocketManager.h +++ b/Core/HLE/SocketManager.h @@ -26,7 +26,7 @@ public: MIN_VALID_INET_SOCKET = 61, }; - InetSocket *AllocSocket(int *index); + InetSocket *CreateSocket(int *index, SocketState state, int domain, int type, int protocol); bool GetInetSocket(int sock, InetSocket **inetSocket); SOCKET GetHostSocketFromInetSocket(int sock); void CloseAll(); diff --git a/Core/HLE/sceNetInet.cpp b/Core/HLE/sceNetInet.cpp index 5f1ca06dfd..1aa38c7204 100644 --- a/Core/HLE/sceNetInet.cpp +++ b/Core/HLE/sceNetInet.cpp @@ -392,40 +392,21 @@ static int sceNetInetSocket(int domain, int type, int protocol) { WARN_LOG(Log::sceNet, "UNTESTED sceNetInetSocket(%i, %i, %i) at %08x", domain, type, protocol, currentMIPS->pc); DEBUG_LOG(Log::sceNet, "Socket: Domain = %s, Type = %s, Protocol = %s", inetSocketDomain2str(domain).c_str(), inetSocketType2str(type).c_str(), inetSocketProto2str(protocol).c_str()); - int hostDomain = convertSocketDomainPSP2Host(domain); - int hostType = convertSocketTypePSP2Host(type); - int hostProtocol = convertSocketProtoPSP2Host(protocol); - - SOCKET hostSock = ::socket(hostDomain, hostType, hostProtocol); - if (hostSock < 0) { - inetLastErrno = socket_errno; - return hleLogError(Log::sceNet, hostSock, "errno = %d", inetLastErrno); - } - - // Register the socket. - 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_socketManager.CreateSocket(&socket, SocketState::UsedNetInet, domain, type, protocol); + if (!inetSock) { + inetLastErrno = socket_errno; + return hleLogError(Log::sceNet, -1, "errno = %d", inetLastErrno); } - inetSock->state = SocketState::UsedNetInet; - inetSock->sock = hostSock; - inetSock->domain = domain; - inetSock->type = type; - inetSock->protocol = protocol; - // Ignore SIGPIPE when supported (ie. BSD/MacOS) - setSockNoSIGPIPE(hostSock, 1); + setSockNoSIGPIPE(inetSock->sock, 1); // TODO: We should always use non-blocking mode and simulate blocking mode - changeBlockingMode(hostSock, 1); + changeBlockingMode(inetSock->sock, 1); // Enable Port Re-use, required for multiple-instance - setSockReuseAddrPort(hostSock); + setSockReuseAddrPort(inetSock->sock); // Disable Connection Reset error on UDP to avoid strange behavior - setUDPConnReset(hostSock, false); + setUDPConnReset(inetSock->sock, false); return hleLogSuccessI(Log::sceNet, socket); }