Add a central location for managing HLE sockets

This commit is contained in:
Henrik Rydgård 2025-01-08 12:04:59 +01:00
parent 3dc2a1034d
commit 2c3f7f6806
12 changed files with 113 additions and 72 deletions

View file

@ -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

View file

@ -580,6 +580,7 @@
<ClCompile Include="HLE\sceUsbAcc.cpp" />
<ClCompile Include="HLE\sceUsbCam.cpp" />
<ClCompile Include="HLE\sceUsbMic.cpp" />
<ClCompile Include="HLE\SocketManager.cpp" />
<ClCompile Include="HW\Atrac3Standalone.cpp" />
<ClCompile Include="HW\BufferQueue.cpp" />
<ClCompile Include="HW\Camera.cpp" />
@ -1199,6 +1200,7 @@
<ClInclude Include="HLE\sceUsbAcc.h" />
<ClInclude Include="HLE\sceUsbCam.h" />
<ClInclude Include="HLE\sceUsbMic.h" />
<ClInclude Include="HLE\SocketManager.h" />
<ClInclude Include="HW\Atrac3Standalone.h" />
<ClInclude Include="HW\Camera.h" />
<ClInclude Include="HW\Display.h" />

View file

@ -1342,6 +1342,9 @@
<ClCompile Include="HLE\NetInetConstants.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
<ClCompile Include="HLE\SocketManager.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ELF\ElfReader.h">
@ -2160,6 +2163,9 @@
<ClInclude Include="HLE\NetInetConstants.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
<ClInclude Include="HLE\SocketManager.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE.TXT" />

View file

@ -0,0 +1,54 @@
#include "Core/HLE/SocketManager.h"
#include "Common/Log.h"
#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];
static std::mutex g_socketMutex; // TODO: Remove once the adhoc thread is gone
int AllocInetSocket() {
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;
}
}
_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<std::mutex> 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<std::mutex> 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;
}
}

34
Core/HLE/SocketManager.h Normal file
View file

@ -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();

View file

@ -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"

View file

@ -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;

View file

@ -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];

View file

@ -182,6 +182,7 @@
<ClInclude Include="..\..\Core\HLE\sceNetInet.h" />
<ClInclude Include="..\..\Core\HLE\sceNetResolver.h" />
<ClInclude Include="..\..\Core\HLE\sceNp2.h" />
<ClInclude Include="..\..\Core\HLE\SocketManager.h" />
<ClInclude Include="..\..\Core\Instance.h" />
<ClInclude Include="..\..\Core\HLE\FunctionWrappers.h" />
<ClInclude Include="..\..\Core\HLE\HLE.h" />
@ -444,6 +445,7 @@
<ClCompile Include="..\..\Core\HLE\sceNetInet.cpp" />
<ClCompile Include="..\..\Core\HLE\sceNetResolver.cpp" />
<ClCompile Include="..\..\Core\HLE\sceNp2.cpp" />
<ClCompile Include="..\..\Core\HLE\SocketManager.cpp" />
<ClCompile Include="..\..\Core\Instance.cpp" />
<ClCompile Include="..\..\Core\HLE\HLE.cpp" />
<ClCompile Include="..\..\Core\HLE\HLEHelperThread.cpp" />

View file

@ -1232,6 +1232,9 @@
<ClCompile Include="..\..\Core\HLE\NetInetConstants.cpp">
<Filter>HLE</Filter>
</ClCompile>
<ClCompile Include="..\..\Core\HLE\SocketManager.cpp">
<Filter>HLE</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
@ -1948,6 +1951,9 @@
<ClInclude Include="..\..\Core\HLE\NetInetConstants.h">
<Filter>HLE</Filter>
</ClInclude>
<ClInclude Include="..\..\Core\HLE\SocketManager.h">
<Filter>HLE</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\ext\gason\LICENSE">

View file

@ -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 \

View file

@ -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 \