diff --git a/CMakeLists.txt b/CMakeLists.txt index b44592b8e0..b923419d0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2178,6 +2178,8 @@ add_library(${CoreLibName} ${CoreLinkType} Core/HLE/AtracCtx2.h Core/HLE/NetInetConstants.cpp Core/HLE/NetInetConstants.h + Core/HLE/SocketManager.cpp + Core/HLE/SocketManager.h Core/HLE/sceAtrac.cpp Core/HLE/sceAtrac.h Core/HLE/sceAudio.cpp diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 6242bc4dc5..dbb6ca5bfa 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -580,6 +580,7 @@ + @@ -1199,6 +1200,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 174dceebb4..ad6cdd3f48 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -1342,6 +1342,9 @@ HLE\Libraries + + HLE\Libraries + @@ -2160,6 +2163,9 @@ HLE\Libraries + + HLE\Libraries + diff --git a/Core/HLE/SocketManager.cpp b/Core/HLE/SocketManager.cpp new file mode 100644 index 0000000000..400d163677 --- /dev/null +++ b/Core/HLE/SocketManager.cpp @@ -0,0 +1,54 @@ +#include "Core/HLE/SocketManager.h" +#include "Common/Log.h" + +#include + +// 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]; +static std::mutex g_socketMutex; // TODO: Remove once the adhoc thread is gone + +int AllocInetSocket() { + std::lock_guard 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; + } + } + _dbg_assert_(false); + ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD."); + return 0; +} + +bool GetInetSocket(int sock, InetSocket **inetSocket) { + std::lock_guard guard(g_socketMutex); + if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(g_inetSockets) || g_inetSockets[sock].state == SocketState::Unused) { + *inetSocket = nullptr; + return false; + } + *inetSocket = &g_inetSockets[sock]; + return true; +} + +// Simplified mappers, only really useful in select/poll +SOCKET GetHostSocketFromInetSocket(int sock) { + std::lock_guard guard(g_socketMutex); + if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(g_inetSockets) || g_inetSockets[sock].state == SocketState::Unused) { + _dbg_assert_(false); + return -1; + } + if (sock == 0) { + // Map 0 to 0, special case. + return 0; + } + return g_inetSockets[sock].sock; +} + +void CloseAllSockets() { + for (auto &sock : g_inetSockets) { + if (sock.state != SocketState::Unused) { + closesocket(sock.sock); + } + sock.state = SocketState::Unused; + sock.sock = 0; + } +} diff --git a/Core/HLE/SocketManager.h b/Core/HLE/SocketManager.h new file mode 100644 index 0000000000..0eaac03273 --- /dev/null +++ b/Core/HLE/SocketManager.h @@ -0,0 +1,34 @@ +#pragma once + +#include "Common/Net/SocketCompat.h" + +// Keep track of who's using a socket. +enum class SocketState { + Unused, + UsedNetInet, + UsedProAdhoc, +}; + +// Internal socket state tracking +struct InetSocket { + SOCKET sock; // native socket + SocketState state; + // NOTE: These are the PSP types for now + int domain; + int type; + int protocol; + // These are the host types for convenience. + int hostDomain; + int hostType; + int hostProtocol; +}; + +#define MIN_VALID_INET_SOCKET 20 +#define VALID_INET_SOCKET_COUNT 256 + +extern InetSocket g_inetSockets[VALID_INET_SOCKET_COUNT]; + +int AllocInetSocket(); +bool GetInetSocket(int sock, InetSocket **inetSocket); +SOCKET GetHostSocketFromInetSocket(int sock); +void CloseAllSockets(); diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index e040fc6b67..67849b3445 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -49,7 +49,6 @@ #include "Core/CoreTiming.h" #include "Core/Core.h" #include "Core/HLE/sceKernelInterrupt.h" -#include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelMemory.h" #include "Core/HLE/sceNetAdhoc.h" #include "Core/Instance.h" diff --git a/Core/HLE/sceNetInet.cpp b/Core/HLE/sceNetInet.cpp index 995d73adc3..f8bf83267a 100644 --- a/Core/HLE/sceNetInet.cpp +++ b/Core/HLE/sceNetInet.cpp @@ -6,6 +6,7 @@ #include "Common/Serialize/SerializeFuncs.h" #include "Common/Serialize/SerializeMap.h" +#include "Core/HLE/SocketManager.h" #include "Core/HLE/HLE.h" #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceNet.h" @@ -22,63 +23,17 @@ #include "Core/Util/PortManager.h" #include "Core/Instance.h" -#define MIN_VALID_SOCKET 20 - int inetLastErrno = 0; // TODO: since errno can only be read once, we should keep track the value to be used on sceNetInetGetErrno bool netInetInited = false; -// 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]; - -static int AllocInetSocket() { - for (int i = MIN_VALID_SOCKET; i < ARRAY_SIZE(g_inetSockets); i++) { - if (g_inetSockets[i].state == SocketState::Unused) { - return i; - } - } - _dbg_assert_(false); - ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD."); - return 0; -} - -static bool GetInetSocket(int sock, InetSocket **inetSocket) { - if (sock < MIN_VALID_SOCKET || sock >= ARRAY_SIZE(g_inetSockets) || g_inetSockets[sock].state == SocketState::Unused) { - *inetSocket = nullptr; - return false; - } - *inetSocket = &g_inetSockets[sock]; - return true; -} - -// Simplified mappers, only really useful in select/poll -static SOCKET GetHostSocketFromInetSocket(int sock) { - if (sock < MIN_VALID_SOCKET || sock >= ARRAY_SIZE(g_inetSockets) || g_inetSockets[sock].state == SocketState::Unused) { - _dbg_assert_(false); - return -1; - } - if (sock == 0) { - // Map 0 to 0, special case. - return 0; - } - return g_inetSockets[sock].sock; -} - void __NetInetShutdown() { if (!netInetInited) { return; } netInetInited = false; - - for (auto &sock : g_inetSockets) { - if (sock.state != SocketState::Unused) { - closesocket(sock.sock); - } - sock.state = SocketState::Unused; - } - - // TODO: Shut down any open sockets here. + CloseAllSockets(); } static int sceNetInetInit() { @@ -250,7 +205,7 @@ int sceNetInetSelect(int nfds, u32 readfdsPtr, u32 writefdsPtr, u32 exceptfdsPtr // Save the mapping during setup. SOCKET hostSockets[256]{}; - for (int i = MIN_VALID_SOCKET; i < nfds; i++) { + for (int i = MIN_VALID_INET_SOCKET; i < nfds; i++) { if (readfds && (NetInetFD_ISSET(i, readfds))) { SOCKET sock = GetHostSocketFromInetSocket(i); hostSockets[i] = sock; @@ -299,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_SOCKET; i < nfds; i++) { + for (int i = MIN_VALID_INET_SOCKET; i < nfds; i++) { if (readfds && hostSockets[i] != 0 && FD_ISSET(hostSockets[i], &rdfds)) { NetInetFD_SET(i, readfds); } @@ -455,7 +410,7 @@ static int sceNetInetSocket(int domain, int type, int protocol) { return hleLogError(Log::sceNet, ERROR_NET_INTERNAL); } InetSocket *inetSock = &g_inetSockets[socket]; - inetSock->state = SocketState::Used; + inetSock->state = SocketState::UsedNetInet; inetSock->sock = hostSock; inetSock->domain = domain; inetSock->type = type; diff --git a/Core/HLE/sceNetInet.h b/Core/HLE/sceNetInet.h index daa319b77d..fb84e14350 100644 --- a/Core/HLE/sceNetInet.h +++ b/Core/HLE/sceNetInet.h @@ -186,24 +186,3 @@ int sceNetApctlConnect(int connIndex); int sceNetInetPoll(u32 fdsPtr, u32 nfds, int timeout); int sceNetApctlTerm(); int sceNetApctlDisconnect(); - -enum class SocketState { - Unused, - Used, -}; - -// Internal socket state tracking -struct InetSocket { - SOCKET sock; // native socket - SocketState state; - // NOTE: These are the PSP types for now - int domain; - int type; - int protocol; - // These are the host types for convenience. - int hostDomain; - int hostType; - int hostProtocol; -}; - -extern InetSocket g_inetSockets[256]; diff --git a/UWP/CoreUWP/CoreUWP.vcxproj b/UWP/CoreUWP/CoreUWP.vcxproj index ac4968d511..a8b36afc1f 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj +++ b/UWP/CoreUWP/CoreUWP.vcxproj @@ -182,6 +182,7 @@ + @@ -444,6 +445,7 @@ + diff --git a/UWP/CoreUWP/CoreUWP.vcxproj.filters b/UWP/CoreUWP/CoreUWP.vcxproj.filters index a2619dff45..109f5311da 100644 --- a/UWP/CoreUWP/CoreUWP.vcxproj.filters +++ b/UWP/CoreUWP/CoreUWP.vcxproj.filters @@ -1232,6 +1232,9 @@ HLE + + HLE + @@ -1948,6 +1951,9 @@ HLE + + HLE + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index a10eac82d2..34b2720c74 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -665,6 +665,7 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/HLE/HLE.cpp \ $(SRC)/Core/HLE/KUBridge.cpp \ $(SRC)/Core/HLE/NetInetConstants.cpp \ + $(SRC)/Core/HLE/SocketManager.cpp \ $(SRC)/Core/HLE/Plugins.cpp \ $(SRC)/Core/HLE/sceAdler.cpp \ $(SRC)/Core/HLE/sceAtrac.cpp \ diff --git a/libretro/Makefile.common b/libretro/Makefile.common index f534527ce9..924a4ff019 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -691,6 +691,7 @@ SOURCES_CXX += \ $(COREDIR)/HLE/HLE.cpp \ $(COREDIR)/HLE/KUBridge.cpp \ $(COREDIR)/HLE/NetInetConstants.cpp \ + $(COREDIR)/HLE/SocketManager.cpp \ $(COREDIR)/HLE/Plugins.cpp \ $(COREDIR)/HLE/sceSha256.cpp \ $(COREDIR)/HLE/sceSircs.cpp \