summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabio Alessandrelli <fabio.alessandrelli@gmail.com>2018-09-22 02:02:10 +0200
committerGitHub <noreply@github.com>2018-09-22 02:02:10 +0200
commit5a03d50921d4d9e33fc3cd4adb1ea663819e2072 (patch)
treed3b288aa016d4a266c98a9a486dcde0ef75eac4d
parentef7b384861d59e566badf1adf28c8b56255c912e (diff)
parent479d4fb7413b2f824ed95d3ac91289e8e8e3cfbd (diff)
Merge pull request #22327 from Faless/defective_by_design_is_the_windows_way
Use select instead of WSAPoll on Windows.
-rw-r--r--drivers/unix/net_socket_posix.cpp56
1 files changed, 52 insertions, 4 deletions
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 9dcc6038ab..07548ab91f 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -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 = &wr;
+ break;
+ case POLL_TYPE_IN_OUT:
+ FD_SET(_sock, &rd);
+ FD_SET(_sock, &wr);
+ rdp = &rd;
+ wrp = &wr;
+ }
+ 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) {