Skip to content

Commit d4ad8c9

Browse files
authored
Merge pull request #19827 from hrydgard/net-inet-socket-remap
sceNetInet socket remap
2 parents 4218b39 + 440fa80 commit d4ad8c9

File tree

14 files changed

+538
-134
lines changed

14 files changed

+538
-134
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2178,6 +2178,8 @@ add_library(${CoreLibName} ${CoreLinkType}
21782178
Core/HLE/AtracCtx2.h
21792179
Core/HLE/NetInetConstants.cpp
21802180
Core/HLE/NetInetConstants.h
2181+
Core/HLE/SocketManager.cpp
2182+
Core/HLE/SocketManager.h
21812183
Core/HLE/sceAtrac.cpp
21822184
Core/HLE/sceAtrac.h
21832185
Core/HLE/sceAudio.cpp

Common/ArmEmitter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
#define IS_SIGNED 1 << 1
3232
#define ROUND_TO_ZERO 1 << 2
3333

34+
// Unclear why we suddenly need this.
35+
#undef VMIN
36+
3437
namespace ArmGen
3538
{
3639
enum ARMReg

Core/Core.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@
580580
<ClCompile Include="HLE\sceUsbAcc.cpp" />
581581
<ClCompile Include="HLE\sceUsbCam.cpp" />
582582
<ClCompile Include="HLE\sceUsbMic.cpp" />
583+
<ClCompile Include="HLE\SocketManager.cpp" />
583584
<ClCompile Include="HW\Atrac3Standalone.cpp" />
584585
<ClCompile Include="HW\BufferQueue.cpp" />
585586
<ClCompile Include="HW\Camera.cpp" />
@@ -1199,6 +1200,7 @@
11991200
<ClInclude Include="HLE\sceUsbAcc.h" />
12001201
<ClInclude Include="HLE\sceUsbCam.h" />
12011202
<ClInclude Include="HLE\sceUsbMic.h" />
1203+
<ClInclude Include="HLE\SocketManager.h" />
12021204
<ClInclude Include="HW\Atrac3Standalone.h" />
12031205
<ClInclude Include="HW\Camera.h" />
12041206
<ClInclude Include="HW\Display.h" />

Core/Core.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,9 @@
13421342
<ClCompile Include="HLE\NetInetConstants.cpp">
13431343
<Filter>HLE\Libraries</Filter>
13441344
</ClCompile>
1345+
<ClCompile Include="HLE\SocketManager.cpp">
1346+
<Filter>HLE\Libraries</Filter>
1347+
</ClCompile>
13451348
</ItemGroup>
13461349
<ItemGroup>
13471350
<ClInclude Include="ELF\ElfReader.h">
@@ -2160,6 +2163,9 @@
21602163
<ClInclude Include="HLE\NetInetConstants.h">
21612164
<Filter>HLE\Libraries</Filter>
21622165
</ClInclude>
2166+
<ClInclude Include="HLE\SocketManager.h">
2167+
<Filter>HLE\Libraries</Filter>
2168+
</ClInclude>
21632169
</ItemGroup>
21642170
<ItemGroup>
21652171
<None Include="..\LICENSE.TXT" />

Core/HLE/SocketManager.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include "Common/Net/SocketCompat.h"
2+
#include "Core/HLE/NetInetConstants.h"
3+
#include "Core/HLE/SocketManager.h"
4+
#include "Common/Log.h"
5+
6+
#include <mutex>
7+
8+
SocketManager g_socketManager;
9+
static std::mutex g_socketMutex; // TODO: Remove once the adhoc thread is gone
10+
11+
InetSocket *SocketManager::CreateSocket(int *index, int *returned_errno, SocketState state, int domain, int type, int protocol) {
12+
_dbg_assert_(state != SocketState::Unused);
13+
14+
int hostDomain = convertSocketDomainPSP2Host(domain);
15+
int hostType = convertSocketTypePSP2Host(type);
16+
int hostProtocol = convertSocketProtoPSP2Host(protocol);
17+
18+
SOCKET hostSock = ::socket(hostDomain, hostType, hostProtocol);
19+
if (hostSock < 0) {
20+
*returned_errno = socket_errno;
21+
return nullptr;
22+
}
23+
24+
std::lock_guard<std::mutex> guard(g_socketMutex);
25+
26+
for (int i = MIN_VALID_INET_SOCKET; i < ARRAY_SIZE(inetSockets_); i++) {
27+
if (inetSockets_[i].state == SocketState::Unused) {
28+
*index = i;
29+
InetSocket *inetSock = inetSockets_ + i;
30+
inetSock->sock = hostSock;
31+
inetSock->state = state;
32+
inetSock->domain = domain;
33+
inetSock->type = type;
34+
inetSock->protocol = protocol;
35+
inetSock->nonblocking = false;
36+
*returned_errno = 0;
37+
return inetSock;
38+
}
39+
}
40+
_dbg_assert_(false);
41+
42+
ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD.");
43+
closesocket(hostSock);
44+
*index = 0;
45+
*returned_errno = ENOMEM; // or something..
46+
return nullptr;
47+
}
48+
49+
bool SocketManager::Close(InetSocket *inetSocket) {
50+
_dbg_assert_(inetSocket->state != SocketState::Unused);
51+
if (closesocket(inetSocket->sock) != 0) {
52+
ERROR_LOG(Log::sceNet, "closesocket(%d) failed", inetSocket->sock);
53+
return false;
54+
}
55+
inetSocket->state = SocketState::Unused;
56+
inetSocket->sock = 0;
57+
return true;
58+
}
59+
60+
bool SocketManager::GetInetSocket(int sock, InetSocket **inetSocket) {
61+
std::lock_guard<std::mutex> guard(g_socketMutex);
62+
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) {
63+
*inetSocket = nullptr;
64+
return false;
65+
}
66+
*inetSocket = inetSockets_ + sock;
67+
return true;
68+
}
69+
70+
// Simplified mappers, only really useful in select/poll
71+
SOCKET SocketManager::GetHostSocketFromInetSocket(int sock) {
72+
std::lock_guard<std::mutex> guard(g_socketMutex);
73+
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) {
74+
_dbg_assert_(false);
75+
return -1;
76+
}
77+
if (sock == 0) {
78+
// Map 0 to 0, special case.
79+
return 0;
80+
}
81+
return inetSockets_[sock].sock;
82+
}
83+
84+
void SocketManager::CloseAll() {
85+
for (auto &sock : inetSockets_) {
86+
if (sock.state != SocketState::Unused) {
87+
closesocket(sock.sock);
88+
}
89+
sock.state = SocketState::Unused;
90+
sock.sock = 0;
91+
}
92+
}
93+
94+
const char *SocketStateToString(SocketState state) {
95+
switch (state) {
96+
case SocketState::Unused: return "unused";
97+
case SocketState::UsedNetInet: return "netInet";
98+
case SocketState::UsedProAdhoc: return "proAdhoc";
99+
default:
100+
return "N/A";
101+
}
102+
}

Core/HLE/SocketManager.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#pragma once
2+
3+
#include "Common/Net/SocketCompat.h"
4+
5+
// Keep track of who's using a socket.
6+
enum class SocketState {
7+
Unused = 0,
8+
UsedNetInet,
9+
UsedProAdhoc,
10+
};
11+
12+
const char *SocketStateToString(SocketState state);
13+
14+
// Internal socket state tracking
15+
struct InetSocket {
16+
SOCKET sock; // native socket
17+
SocketState state;
18+
// NOTE: These are the PSP types. Can be converted to the host types if needed.
19+
int domain;
20+
int type;
21+
int protocol;
22+
bool nonblocking;
23+
};
24+
25+
// Only use this for sockets whose ID are exposed to the game.
26+
// Don't really need to bother with the others, as the game doesn't know about them.
27+
class SocketManager {
28+
public:
29+
enum {
30+
VALID_INET_SOCKET_COUNT = 256,
31+
MIN_VALID_INET_SOCKET = 1,
32+
};
33+
34+
InetSocket *CreateSocket(int *index, int *returned_errno, SocketState state, int domain, int type, int protocol);
35+
bool GetInetSocket(int sock, InetSocket **inetSocket);
36+
SOCKET GetHostSocketFromInetSocket(int sock);
37+
bool Close(InetSocket *inetSocket);
38+
void CloseAll();
39+
40+
// For debugger
41+
const InetSocket *Sockets() {
42+
return inetSockets_;
43+
}
44+
45+
private:
46+
// We use this array from MIN_VALID_INET_SOCKET and forward. It's probably not a good idea to return 0 as a socket.
47+
InetSocket inetSockets_[VALID_INET_SOCKET_COUNT];
48+
};
49+
50+
extern SocketManager g_socketManager;

Core/HLE/proAdhoc.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
#include "Core/CoreTiming.h"
5050
#include "Core/Core.h"
5151
#include "Core/HLE/sceKernelInterrupt.h"
52-
#include "Core/HLE/sceKernelThread.h"
5352
#include "Core/HLE/sceKernelMemory.h"
5453
#include "Core/HLE/sceNetAdhoc.h"
5554
#include "Core/Instance.h"
@@ -94,7 +93,9 @@ int actionAfterMatchingMipsCall;
9493
// Broadcast MAC
9594
uint8_t broadcastMAC[ETHER_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
9695

96+
// NOTE: This does not need to be managed by the socket manager - not exposed to the game.
9797
std::atomic<int> metasocket((int)INVALID_SOCKET);
98+
9899
SceNetAdhocctlParameter parameter;
99100
SceNetAdhocctlAdhocId product_code;
100101
std::thread friendFinderThread;
@@ -281,6 +282,7 @@ SceNetAdhocctlPeerInfo* findFriendByIP(uint32_t ip) {
281282
return peer;
282283
}
283284

285+
// fd is a host socket
284286
int IsSocketReady(int fd, bool readfd, bool writefd, int* errorcode, int timeoutUS) {
285287
fd_set readfds, writefds;
286288
timeval tval;
@@ -1318,7 +1320,7 @@ int GetChatMessageCount() {
13181320
}
13191321

13201322
// TODO: We should probably change this thread into PSPThread (or merging it into the existing AdhocThread PSPThread) as there are too many global vars being used here which also being used within some HLEs
1321-
int friendFinder(){
1323+
int friendFinder() {
13221324
SetCurrentThreadName("FriendFinder");
13231325
auto n = GetI18NCategory(I18NCat::NETWORKING);
13241326
// Receive Buffer

0 commit comments

Comments
 (0)