mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
88 lines
2.5 KiB
C++
88 lines
2.5 KiB
C++
#include "Common/Net/SocketCompat.h"
|
|
#include "Core/HLE/NetInetConstants.h"
|
|
#include "Core/HLE/SocketManager.h"
|
|
#include "Common/Log.h"
|
|
|
|
#include <mutex>
|
|
|
|
SocketManager g_socketManager;
|
|
static std::mutex g_socketMutex; // TODO: Remove once the adhoc thread is gone
|
|
|
|
InetSocket *SocketManager::CreateSocket(int *index, SocketState state, int domain, int type, int protocol) {
|
|
_dbg_assert_(state != SocketState::Unused);
|
|
|
|
int hostDomain = convertSocketDomainPSP2Host(domain);
|
|
int hostType = convertSocketTypePSP2Host(type);
|
|
int hostProtocol = convertSocketProtoPSP2Host(protocol);
|
|
|
|
SOCKET hostSock = ::socket(hostDomain, hostType, hostProtocol);
|
|
if (hostSock < 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> guard(g_socketMutex);
|
|
|
|
for (int i = MIN_VALID_INET_SOCKET; i < ARRAY_SIZE(inetSockets_); i++) {
|
|
if (inetSockets_[i].state == SocketState::Unused) {
|
|
*index = i;
|
|
InetSocket *inetSock = inetSockets_ + i;
|
|
inetSock->sock = hostSock;
|
|
inetSock->state = state;
|
|
inetSock->domain = domain;
|
|
inetSock->type = type;
|
|
inetSock->protocol = protocol;
|
|
return inetSock;
|
|
}
|
|
}
|
|
_dbg_assert_(false);
|
|
|
|
ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD.");
|
|
closesocket(hostSock);
|
|
*index = 0;
|
|
return nullptr;
|
|
}
|
|
|
|
bool SocketManager::Close(InetSocket *inetSocket) {
|
|
_dbg_assert_(inetSocket->state != SocketState::Unused);
|
|
if (closesocket(inetSocket->sock) != 0) {
|
|
ERROR_LOG(Log::sceNet, "closesocket(%d) failed", inetSocket->sock);
|
|
return false;
|
|
}
|
|
inetSocket->state = SocketState::Unused;
|
|
inetSocket->sock = 0;
|
|
return true;
|
|
}
|
|
|
|
bool SocketManager::GetInetSocket(int sock, InetSocket **inetSocket) {
|
|
std::lock_guard<std::mutex> guard(g_socketMutex);
|
|
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) {
|
|
*inetSocket = nullptr;
|
|
return false;
|
|
}
|
|
*inetSocket = inetSockets_ + sock;
|
|
return true;
|
|
}
|
|
|
|
// Simplified mappers, only really useful in select/poll
|
|
SOCKET SocketManager::GetHostSocketFromInetSocket(int sock) {
|
|
std::lock_guard<std::mutex> guard(g_socketMutex);
|
|
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) {
|
|
_dbg_assert_(false);
|
|
return -1;
|
|
}
|
|
if (sock == 0) {
|
|
// Map 0 to 0, special case.
|
|
return 0;
|
|
}
|
|
return inetSockets_[sock].sock;
|
|
}
|
|
|
|
void SocketManager::CloseAll() {
|
|
for (auto &sock : inetSockets_) {
|
|
if (sock.state != SocketState::Unused) {
|
|
closesocket(sock.sock);
|
|
}
|
|
sock.state = SocketState::Unused;
|
|
sock.sock = 0;
|
|
}
|
|
}
|