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 \