mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
WSAPoll workaround
This commit is contained in:
parent
9b77febd10
commit
90e4fe23c5
@ -79,6 +79,35 @@ void fmt_class_string<sys_net_error>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Workaround function for WSAPoll not reporting failed connections
|
||||
void windows_poll(pollfd* fds, unsigned long nfds, int timeout, bool *connecting)
|
||||
{
|
||||
int r = ::WSAPoll(fds, nfds, timeout);
|
||||
for (unsigned long i = 0; i < nfds; i++)
|
||||
{
|
||||
if (connecting[i])
|
||||
{
|
||||
if (!fds[i].revents)
|
||||
{
|
||||
int error = 0;
|
||||
socklen_t intlen = sizeof(error);
|
||||
if (getsockopt(fds[i].fd, SOL_SOCKET, SO_ERROR, (char*)&error, &intlen) == -1 || error != 0)
|
||||
{
|
||||
// Connection silently failed
|
||||
connecting[i] = false;
|
||||
fds[i].revents = POLLERR | POLLHUP | (fds[i].events & (POLLIN | POLLOUT));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
connecting[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Error helper functions
|
||||
static sys_net_error get_last_error(bool is_blocking, int native_error = 0)
|
||||
{
|
||||
@ -186,12 +215,15 @@ struct network_thread
|
||||
s_to_awake.clear();
|
||||
|
||||
::pollfd fds[lv2_socket::id_count]{};
|
||||
#ifdef _WIN32
|
||||
bool connecting[lv2_socket::id_count]{};
|
||||
#endif
|
||||
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
// Wait with 1ms timeout
|
||||
#ifdef _WIN32
|
||||
::WSAPoll(fds, socklist.size(), 1);
|
||||
windows_poll(fds, socklist.size(), 1, connecting);
|
||||
#else
|
||||
::poll(fds, socklist.size(), 1);
|
||||
#endif
|
||||
@ -204,6 +236,10 @@ struct network_thread
|
||||
|
||||
lv2_socket& sock = *socklist[i];
|
||||
|
||||
#ifdef _WIN32
|
||||
sock.is_connecting = connecting[i];
|
||||
#endif
|
||||
|
||||
if (fds[i].revents & (POLLIN | POLLHUP) && socklist[i]->events.test_and_reset(lv2_socket::poll::read))
|
||||
events += lv2_socket::poll::read;
|
||||
if (fds[i].revents & POLLOUT && socklist[i]->events.test_and_reset(lv2_socket::poll::write))
|
||||
@ -265,6 +301,9 @@ struct network_thread
|
||||
(events & lv2_socket::poll::write ? POLLOUT : 0) |
|
||||
0;
|
||||
fds[i].revents = 0;
|
||||
#ifdef _WIN32
|
||||
connecting[i] = socklist[i]->is_connecting;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -522,6 +561,9 @@ error_code sys_net_bnet_connect(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr
|
||||
{
|
||||
if (result == SYS_NET_EWOULDBLOCK)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
sock.is_connecting = true;
|
||||
#endif
|
||||
result = SYS_NET_EINPROGRESS;
|
||||
}
|
||||
|
||||
@ -1577,6 +1619,9 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr<sys_net_pollfd> fds, s32 n
|
||||
reader_lock lock(id_manager::g_mutex);
|
||||
|
||||
::pollfd _fds[1024]{};
|
||||
#ifdef _WIN32
|
||||
bool connecting[1024]{};
|
||||
#endif
|
||||
|
||||
for (s32 i = 0; i < nfds; i++)
|
||||
{
|
||||
@ -1597,6 +1642,9 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr<sys_net_pollfd> fds, s32 n
|
||||
_fds[i].events |= POLLIN;
|
||||
if (fds[i].events & SYS_NET_POLLOUT)
|
||||
_fds[i].events |= POLLOUT;
|
||||
#ifdef _WIN32
|
||||
connecting[i] = sock->is_connecting;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1606,7 +1654,7 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr<sys_net_pollfd> fds, s32 n
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
::WSAPoll(_fds, nfds, 0);
|
||||
windows_poll(_fds, nfds, 0, connecting);
|
||||
#else
|
||||
::poll(_fds, nfds, 0);
|
||||
#endif
|
||||
@ -1641,6 +1689,10 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr<sys_net_pollfd> fds, s32 n
|
||||
{
|
||||
std::lock_guard lock(sock->mutex);
|
||||
|
||||
#ifdef _WIN32
|
||||
sock->is_connecting = connecting[i];
|
||||
#endif
|
||||
|
||||
bs_t<lv2_socket::poll> selected = +lv2_socket::poll::error;
|
||||
|
||||
if (fds[i].events & SYS_NET_POLLIN)
|
||||
@ -1737,6 +1789,9 @@ error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr<sys_net_fd_set
|
||||
reader_lock lock(id_manager::g_mutex);
|
||||
|
||||
::pollfd _fds[1024]{};
|
||||
#ifdef _WIN32
|
||||
bool connecting[1024]{};
|
||||
#endif
|
||||
|
||||
for (s32 i = 0; i < nfds; i++)
|
||||
{
|
||||
@ -1766,6 +1821,9 @@ error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr<sys_net_fd_set
|
||||
_fds[i].events |= POLLIN;
|
||||
if (selected & lv2_socket::poll::write)
|
||||
_fds[i].events |= POLLOUT;
|
||||
#ifdef _WIN32
|
||||
connecting[i] = sock->is_connecting;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1774,7 +1832,7 @@ error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr<sys_net_fd_set
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
::WSAPoll(_fds, nfds, 0);
|
||||
windows_poll(_fds, nfds, 0, connecting);
|
||||
#else
|
||||
::poll(_fds, nfds, 0);
|
||||
#endif
|
||||
@ -1827,6 +1885,10 @@ error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr<sys_net_fd_set
|
||||
{
|
||||
std::lock_guard lock(sock->mutex);
|
||||
|
||||
#ifdef _WIN32
|
||||
sock->is_connecting = connecting[i];
|
||||
#endif
|
||||
|
||||
sock->events += selected;
|
||||
sock->queue.emplace_back(ppu.id, [sock, selected, i, &rread, &rwrite, &rexcept, &signaled, &ppu](bs_t<lv2_socket::poll> events)
|
||||
{
|
||||
|
@ -336,6 +336,8 @@ struct lv2_socket final
|
||||
#ifdef _WIN32
|
||||
// Remember events (WSAEnumNetworkEvents)
|
||||
u32 ev_set = 0;
|
||||
// Tracks connect for WSAPoll workaround
|
||||
bool is_connecting = false;
|
||||
#endif
|
||||
|
||||
// Native socket (must be non-blocking)
|
||||
|
Loading…
Reference in New Issue
Block a user