mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-06-03 22:45:00 -06:00
Feat: Further refinemets
This commit is contained in:
parent
e763e90c2a
commit
c576aefa9f
@ -727,13 +727,13 @@ int PS4_SYSV_ABI sceNetEpollControl(OrbisNetId epollid, OrbisNetEpollFlag op, Or
|
|||||||
}
|
}
|
||||||
|
|
||||||
// P2P dgram sockets only support EPOLLIN (matches PS4 kernel behavior)
|
// P2P dgram sockets only support EPOLLIN (matches PS4 kernel behavior)
|
||||||
auto epoll_events_mod = event->events;
|
auto epoll_events = event->events;
|
||||||
if (file->socket->socket_type == ORBIS_NET_SOCK_DGRAM_P2P) {
|
if (file->socket->socket_type == ORBIS_NET_SOCK_DGRAM_P2P) {
|
||||||
epoll_events_mod &= ORBIS_NET_EPOLLIN;
|
epoll_events &= ORBIS_NET_EPOLLIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __FreeBSD__
|
#ifndef __FreeBSD__
|
||||||
epoll_event native_event = {.events = ConvertEpollEventsIn(epoll_events_mod),
|
epoll_event native_event = {.events = ConvertEpollEventsIn(epoll_events),
|
||||||
.data = {.fd = id}};
|
.data = {.fd = id}};
|
||||||
ASSERT(epoll_ctl(epoll->epoll_fd, EPOLL_CTL_MOD, *native_handle, &native_event) == 0);
|
ASSERT(epoll_ctl(epoll->epoll_fd, EPOLL_CTL_MOD, *native_handle, &native_event) == 0);
|
||||||
#endif
|
#endif
|
||||||
@ -893,6 +893,9 @@ int PS4_SYSV_ABI sceNetEpollWait(OrbisNetId epollid, OrbisNetEpollEvent* events,
|
|||||||
LOG_TRACE(Lib_Net, "timed out");
|
LOG_TRACE(Lib_Net, "timed out");
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < result; ++j) {
|
for (int j = 0; j < result; ++j) {
|
||||||
|
if (i >= maxevents) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
const auto& current_event = native_events[j];
|
const auto& current_event = native_events[j];
|
||||||
// Skip the abort fd event (registered with data.fd = -1)
|
// Skip the abort fd event (registered with data.fd = -1)
|
||||||
if (current_event.data.fd == -1) {
|
if (current_event.data.fd == -1) {
|
||||||
@ -1734,8 +1737,7 @@ int PS4_SYSV_ABI sceNetSysctl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetTerm() {
|
int PS4_SYSV_ABI sceNetTerm() {
|
||||||
LOG_DEBUG(Lib_Net, "called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
g_isNetInitialized = false;
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,13 @@
|
|||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "net_epoll.h"
|
#include "net_epoll.h"
|
||||||
#ifdef __linux__
|
#ifdef _WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#elif defined(__linux__)
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
|
#else
|
||||||
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Libraries::Net {
|
namespace Libraries::Net {
|
||||||
@ -54,30 +59,85 @@ Epoll::Epoll(const char* name_) : name(name_ ? name_ : "anon"), epoll_fd(epoll_c
|
|||||||
#else
|
#else
|
||||||
ASSERT(epoll_fd != -1);
|
ASSERT(epoll_fd != -1);
|
||||||
#endif
|
#endif
|
||||||
#ifdef __linux__
|
|
||||||
|
// Set up the abort wake mechanism and register it in epoll with sentinel data.fd = -1.
|
||||||
|
// Linux: eventfd, macOS/BSD: self-pipe, Windows: loopback UDP socket.
|
||||||
|
#ifdef _WIN32
|
||||||
|
abort_sock = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
ASSERT(abort_sock != INVALID_SOCKET);
|
||||||
|
sockaddr_in addr{};
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
|
addr.sin_port = 0; // OS picks an ephemeral port
|
||||||
|
ASSERT(::bind(abort_sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == 0);
|
||||||
|
// Connect to self so we can use send() in Abort()
|
||||||
|
socklen_t addrlen = sizeof(addr);
|
||||||
|
ASSERT(::getsockname(abort_sock, reinterpret_cast<sockaddr*>(&addr), &addrlen) == 0);
|
||||||
|
ASSERT(::connect(abort_sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == 0);
|
||||||
|
u_long nonblocking = 1;
|
||||||
|
ASSERT(::ioctlsocket(abort_sock, FIONBIO, &nonblocking) == 0);
|
||||||
|
epoll_event ev = {.events = EPOLLIN, .data = {.fd = -1}};
|
||||||
|
ASSERT(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, abort_sock, &ev) == 0);
|
||||||
|
#elif defined(__linux__)
|
||||||
abort_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
|
abort_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
|
||||||
ASSERT(abort_fd != -1);
|
ASSERT(abort_fd != -1);
|
||||||
epoll_event ev = {.events = EPOLLIN, .data = {.fd = -1}};
|
epoll_event ev = {.events = EPOLLIN, .data = {.fd = -1}};
|
||||||
ASSERT(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, abort_fd, &ev) == 0);
|
ASSERT(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, abort_fd, &ev) == 0);
|
||||||
|
#else
|
||||||
|
// Self-pipe for macOS/BSD
|
||||||
|
int r = ::pipe(abort_pipe);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
// Set both ends non-blocking
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
int flags = ::fcntl(abort_pipe[i], F_GETFL);
|
||||||
|
::fcntl(abort_pipe[i], F_SETFL, flags | O_NONBLOCK);
|
||||||
|
::fcntl(abort_pipe[i], F_SETFD, FD_CLOEXEC);
|
||||||
|
}
|
||||||
|
epoll_event ev = {.events = EPOLLIN, .data = {.fd = -1}};
|
||||||
|
ASSERT(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, abort_pipe[0], &ev) == 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Epoll::Abort() {
|
void Epoll::Abort() {
|
||||||
aborted.store(true, std::memory_order_release);
|
aborted.store(true, std::memory_order_release);
|
||||||
#ifdef __linux__
|
#ifdef _WIN32
|
||||||
|
if (abort_sock != INVALID_SOCKET) {
|
||||||
|
char byte = 1;
|
||||||
|
(void)::send(abort_sock, &byte, 1, 0);
|
||||||
|
}
|
||||||
|
#elif defined(__linux__)
|
||||||
if (abort_fd != -1) {
|
if (abort_fd != -1) {
|
||||||
uint64_t val = 1;
|
uint64_t val = 1;
|
||||||
::write(abort_fd, &val, sizeof(val));
|
(void)::write(abort_fd, &val, sizeof(val));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (abort_pipe[1] != -1) {
|
||||||
|
char byte = 1;
|
||||||
|
(void)::write(abort_pipe[1], &byte, 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Epoll::ClearAbort() {
|
void Epoll::ClearAbort() {
|
||||||
aborted.store(false, std::memory_order_release);
|
aborted.store(false, std::memory_order_release);
|
||||||
#ifdef __linux__
|
#ifdef _WIN32
|
||||||
|
if (abort_sock != INVALID_SOCKET) {
|
||||||
|
char buf[64];
|
||||||
|
// Drain any pending data
|
||||||
|
while (::recv(abort_sock, buf, sizeof(buf), 0) > 0) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(__linux__)
|
||||||
if (abort_fd != -1) {
|
if (abort_fd != -1) {
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
::read(abort_fd, &val, sizeof(val));
|
(void)::read(abort_fd, &val, sizeof(val));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (abort_pipe[0] != -1) {
|
||||||
|
char buf[64];
|
||||||
|
// Drain the pipe
|
||||||
|
while (::read(abort_pipe[0], buf, sizeof(buf)) > 0) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -85,17 +145,29 @@ void Epoll::ClearAbort() {
|
|||||||
void Epoll::Destroy() noexcept {
|
void Epoll::Destroy() noexcept {
|
||||||
events.clear();
|
events.clear();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
if (abort_sock != INVALID_SOCKET) {
|
||||||
|
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, abort_sock, nullptr);
|
||||||
|
::closesocket(abort_sock);
|
||||||
|
abort_sock = INVALID_SOCKET;
|
||||||
|
}
|
||||||
epoll_close(epoll_fd);
|
epoll_close(epoll_fd);
|
||||||
epoll_fd = nullptr;
|
epoll_fd = nullptr;
|
||||||
#else
|
#else
|
||||||
close(epoll_fd);
|
|
||||||
epoll_fd = -1;
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if (abort_fd != -1) {
|
if (abort_fd != -1) {
|
||||||
close(abort_fd);
|
close(abort_fd);
|
||||||
abort_fd = -1;
|
abort_fd = -1;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
if (abort_pipe[i] != -1) {
|
||||||
|
close(abort_pipe[i]);
|
||||||
|
abort_pipe[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
close(epoll_fd);
|
||||||
|
epoll_fd = -1;
|
||||||
#endif
|
#endif
|
||||||
name = "";
|
name = "";
|
||||||
destroyed = true;
|
destroyed = true;
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include <wepoll.h>
|
#include <wepoll.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO: FreeBSD requires libepoll-shim for epoll support
|
||||||
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
|
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -35,8 +36,12 @@ struct Epoll {
|
|||||||
epoll_handle epoll_fd;
|
epoll_handle epoll_fd;
|
||||||
std::deque<u32> async_resolutions{};
|
std::deque<u32> async_resolutions{};
|
||||||
std::atomic<bool> aborted{false};
|
std::atomic<bool> aborted{false};
|
||||||
#ifdef __linux__
|
#ifdef _WIN32
|
||||||
int abort_fd = -1;
|
SOCKET abort_sock = INVALID_SOCKET; // loopback UDP socket for abort wake
|
||||||
|
#elif defined(__linux__)
|
||||||
|
int abort_fd = -1; // eventfd for abort wake
|
||||||
|
#else
|
||||||
|
int abort_pipe[2] = {-1, -1}; // self-pipe for abort wake (macOS/BSD)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
explicit Epoll(const char* name_);
|
explicit Epoll(const char* name_);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user