Merge pull request #22327 from Faless/defective_by_design_is_the_windows_way

Use select instead of WSAPoll on Windows.
This commit is contained in:
Fabio Alessandrelli 2018-09-22 02:02:10 +02:00 committed by GitHub
commit 5a03d50921
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 52 additions and 4 deletions

View File

@ -68,7 +68,6 @@
#define SOCK_BUF(x) x
#define SOCK_CBUF(x) x
#define SOCK_IOCTL ioctl
#define SOCK_POLL ::poll
#define SOCK_CLOSE ::close
/* Windows */
@ -80,7 +79,6 @@
#define SOCK_BUF(x) (char *)(x)
#define SOCK_CBUF(x) (const char *)(x)
#define SOCK_IOCTL ioctlsocket
#define SOCK_POLL WSAPoll
#define SOCK_CLOSE closesocket
// Windows doesn't have this flag
@ -331,10 +329,58 @@ Error NetSocketPosix::connect_to_host(IP_Address p_host, uint16_t p_port) {
return OK;
}
Error NetSocketPosix::poll(PollType p_type, int timeout) const {
Error NetSocketPosix::poll(PollType p_type, int p_timeout) const {
ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED);
#if defined(WINDOWS_ENABLED)
bool ready = false;
fd_set rd, wr, ex;
fd_set *rdp = NULL;
fd_set *wrp = NULL;
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&ex);
FD_SET(_sock, &ex);
struct timeval timeout = { p_timeout, 0 };
// For blocking operation, pass NULL timeout pointer to select.
struct timeval *tp = NULL;
if (p_timeout >= 0) {
// If timeout is non-negative, we want to specify the timeout instead.
tp = &timeout;
}
switch (p_type) {
case POLL_TYPE_IN:
FD_SET(_sock, &rd);
rdp = &rd;
break;
case POLL_TYPE_OUT:
FD_SET(_sock, &wr);
wrp = ≀
break;
case POLL_TYPE_IN_OUT:
FD_SET(_sock, &rd);
FD_SET(_sock, &wr);
rdp = &rd;
wrp = ≀
}
int ret = select(1, rdp, wrp, &ex, tp);
ERR_FAIL_COND_V(ret == SOCKET_ERROR, FAILED);
if (ret == 0)
return ERR_BUSY;
ERR_FAIL_COND_V(FD_ISSET(_sock, &ex), FAILED);
if (rdp && FD_ISSET(_sock, rdp))
ready = true;
if (wrp && FD_ISSET(_sock, wrp))
ready = true;
return ready ? OK : ERR_BUSY;
#else
struct pollfd pfd;
pfd.fd = _sock;
pfd.events = POLLIN;
@ -351,14 +397,16 @@ Error NetSocketPosix::poll(PollType p_type, int timeout) const {
pfd.events = POLLOUT || POLLIN;
}
int ret = SOCK_POLL(&pfd, 1, timeout);
int ret = ::poll(&pfd, 1, p_timeout);
ERR_FAIL_COND_V(ret < 0, FAILED);
ERR_FAIL_COND_V(pfd.revents & POLLERR, FAILED);
if (ret == 0)
return ERR_BUSY;
return OK;
#endif
}
Error NetSocketPosix::recv(uint8_t *p_buffer, int p_len, int &r_read) {