mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 22:11:26 +12:00
WSAPoll workaround
This commit is contained in:
parent
9b77febd10
commit
90e4fe23c5
2 changed files with 67 additions and 3 deletions
|
@ -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
|
// Error helper functions
|
||||||
static sys_net_error get_last_error(bool is_blocking, int native_error = 0)
|
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();
|
s_to_awake.clear();
|
||||||
|
|
||||||
::pollfd fds[lv2_socket::id_count]{};
|
::pollfd fds[lv2_socket::id_count]{};
|
||||||
|
#ifdef _WIN32
|
||||||
|
bool connecting[lv2_socket::id_count]{};
|
||||||
|
#endif
|
||||||
|
|
||||||
while (thread_ctrl::state() != thread_state::aborting)
|
while (thread_ctrl::state() != thread_state::aborting)
|
||||||
{
|
{
|
||||||
// Wait with 1ms timeout
|
// Wait with 1ms timeout
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
::WSAPoll(fds, socklist.size(), 1);
|
windows_poll(fds, socklist.size(), 1, connecting);
|
||||||
#else
|
#else
|
||||||
::poll(fds, socklist.size(), 1);
|
::poll(fds, socklist.size(), 1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -204,6 +236,10 @@ struct network_thread
|
||||||
|
|
||||||
lv2_socket& sock = *socklist[i];
|
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))
|
if (fds[i].revents & (POLLIN | POLLHUP) && socklist[i]->events.test_and_reset(lv2_socket::poll::read))
|
||||||
events += lv2_socket::poll::read;
|
events += lv2_socket::poll::read;
|
||||||
if (fds[i].revents & POLLOUT && socklist[i]->events.test_and_reset(lv2_socket::poll::write))
|
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) |
|
(events & lv2_socket::poll::write ? POLLOUT : 0) |
|
||||||
0;
|
0;
|
||||||
fds[i].revents = 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)
|
if (result == SYS_NET_EWOULDBLOCK)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
sock.is_connecting = true;
|
||||||
|
#endif
|
||||||
result = SYS_NET_EINPROGRESS;
|
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);
|
reader_lock lock(id_manager::g_mutex);
|
||||||
|
|
||||||
::pollfd _fds[1024]{};
|
::pollfd _fds[1024]{};
|
||||||
|
#ifdef _WIN32
|
||||||
|
bool connecting[1024]{};
|
||||||
|
#endif
|
||||||
|
|
||||||
for (s32 i = 0; i < nfds; i++)
|
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;
|
_fds[i].events |= POLLIN;
|
||||||
if (fds[i].events & SYS_NET_POLLOUT)
|
if (fds[i].events & SYS_NET_POLLOUT)
|
||||||
_fds[i].events |= POLLOUT;
|
_fds[i].events |= POLLOUT;
|
||||||
|
#ifdef _WIN32
|
||||||
|
connecting[i] = sock->is_connecting;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1606,7 +1654,7 @@ error_code sys_net_bnet_poll(ppu_thread& ppu, vm::ptr<sys_net_pollfd> fds, s32 n
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
::WSAPoll(_fds, nfds, 0);
|
windows_poll(_fds, nfds, 0, connecting);
|
||||||
#else
|
#else
|
||||||
::poll(_fds, nfds, 0);
|
::poll(_fds, nfds, 0);
|
||||||
#endif
|
#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);
|
std::lock_guard lock(sock->mutex);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
sock->is_connecting = connecting[i];
|
||||||
|
#endif
|
||||||
|
|
||||||
bs_t<lv2_socket::poll> selected = +lv2_socket::poll::error;
|
bs_t<lv2_socket::poll> selected = +lv2_socket::poll::error;
|
||||||
|
|
||||||
if (fds[i].events & SYS_NET_POLLIN)
|
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);
|
reader_lock lock(id_manager::g_mutex);
|
||||||
|
|
||||||
::pollfd _fds[1024]{};
|
::pollfd _fds[1024]{};
|
||||||
|
#ifdef _WIN32
|
||||||
|
bool connecting[1024]{};
|
||||||
|
#endif
|
||||||
|
|
||||||
for (s32 i = 0; i < nfds; i++)
|
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;
|
_fds[i].events |= POLLIN;
|
||||||
if (selected & lv2_socket::poll::write)
|
if (selected & lv2_socket::poll::write)
|
||||||
_fds[i].events |= POLLOUT;
|
_fds[i].events |= POLLOUT;
|
||||||
|
#ifdef _WIN32
|
||||||
|
connecting[i] = sock->is_connecting;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1774,7 +1832,7 @@ error_code sys_net_bnet_select(ppu_thread& ppu, s32 nfds, vm::ptr<sys_net_fd_set
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
::WSAPoll(_fds, nfds, 0);
|
windows_poll(_fds, nfds, 0, connecting);
|
||||||
#else
|
#else
|
||||||
::poll(_fds, nfds, 0);
|
::poll(_fds, nfds, 0);
|
||||||
#endif
|
#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);
|
std::lock_guard lock(sock->mutex);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
sock->is_connecting = connecting[i];
|
||||||
|
#endif
|
||||||
|
|
||||||
sock->events += selected;
|
sock->events += selected;
|
||||||
sock->queue.emplace_back(ppu.id, [sock, selected, i, &rread, &rwrite, &rexcept, &signaled, &ppu](bs_t<lv2_socket::poll> events)
|
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
|
#ifdef _WIN32
|
||||||
// Remember events (WSAEnumNetworkEvents)
|
// Remember events (WSAEnumNetworkEvents)
|
||||||
u32 ev_set = 0;
|
u32 ev_set = 0;
|
||||||
|
// Tracks connect for WSAPoll workaround
|
||||||
|
bool is_connecting = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Native socket (must be non-blocking)
|
// Native socket (must be non-blocking)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue