Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/HLE/SocketManager.cpp
3186 views
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 = {}; // Reset to default.
31
inetSock->sock = hostSock;
32
inetSock->state = state;
33
inetSock->domain = domain;
34
inetSock->type = type;
35
inetSock->protocol = protocol;
36
inetSock->nonblocking = false;
37
*returned_errno = 0;
38
return inetSock;
39
}
40
}
41
_dbg_assert_(false);
42
43
ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD.");
44
closesocket(hostSock);
45
*index = 0;
46
*returned_errno = ENOMEM; // or something..
47
return nullptr;
48
}
49
50
InetSocket *SocketManager::AdoptSocket(int *index, SOCKET hostSocket, const InetSocket *derive) {
51
std::lock_guard<std::mutex> guard(g_socketMutex);
52
53
for (int i = MIN_VALID_INET_SOCKET; i < ARRAY_SIZE(inetSockets_); i++) {
54
if (inetSockets_[i].state == SocketState::Unused) {
55
*index = i;
56
57
InetSocket *inetSock = inetSockets_ + i;
58
inetSock->sock = hostSocket;
59
inetSock->state = derive->state;
60
inetSock->domain = derive->domain;
61
inetSock->type = derive->type;
62
inetSock->protocol = derive->protocol;
63
inetSock->nonblocking = derive->nonblocking; // should we inherit blocking state?
64
return inetSock;
65
}
66
}
67
68
// No space? Return nullptr and let the caller handle it. Shouldn't ever happen.
69
*index = 0;
70
return nullptr;
71
}
72
73
bool SocketManager::Close(InetSocket *inetSocket) {
74
_dbg_assert_(inetSocket->state != SocketState::Unused);
75
if (closesocket(inetSocket->sock) != 0) {
76
ERROR_LOG(Log::sceNet, "closesocket(%d) failed", inetSocket->sock);
77
return false;
78
}
79
inetSocket->state = SocketState::Unused;
80
inetSocket->sock = 0;
81
return true;
82
}
83
84
bool SocketManager::GetInetSocket(int sock, InetSocket **inetSocket) {
85
std::lock_guard<std::mutex> guard(g_socketMutex);
86
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) {
87
*inetSocket = nullptr;
88
return false;
89
}
90
*inetSocket = inetSockets_ + sock;
91
return true;
92
}
93
94
// Simplified mappers, only really useful in select/poll
95
SOCKET SocketManager::GetHostSocketFromInetSocket(int sock) {
96
std::lock_guard<std::mutex> guard(g_socketMutex);
97
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) {
98
_dbg_assert_(false);
99
return -1;
100
}
101
if (sock == 0) {
102
// Map 0 to 0, special case.
103
return 0;
104
}
105
return inetSockets_[sock].sock;
106
}
107
108
void SocketManager::CloseAll() {
109
for (auto &sock : inetSockets_) {
110
if (sock.state != SocketState::Unused) {
111
closesocket(sock.sock);
112
}
113
sock.state = SocketState::Unused;
114
sock.sock = 0;
115
}
116
}
117
118
const char *SocketStateToString(SocketState state) {
119
switch (state) {
120
case SocketState::Unused: return "unused";
121
case SocketState::UsedNetInet: return "netInet";
122
case SocketState::UsedProAdhoc: return "proAdhoc";
123
default:
124
return "N/A";
125
}
126
}
127
128