From 193da820b271ad2d64914517472d3f6dfa83323b Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Thu, 22 Aug 2019 10:34:17 -0700 Subject: [PATCH] Windows: use select instead of WSAPoll, through a poll wrapper --- CHANGELOG.md | 3 ++ ixwebsocket/IXNetSystem.cpp | 77 ++++++++++++++++++++++++++-- ixwebsocket/IXNetSystem.h | 10 ++-- ixwebsocket/IXSocket.cpp | 2 +- ws/ixcobra/IXCobraMetricsPublisher.h | 2 +- 5 files changed, 84 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0fc2029..ba3a36c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Changelog All notable changes to this project will be documented in this file. +## [5.0.5] - 2019-08-22 +- Windows: use select instead of WSAPoll, through a poll wrapper + ## [5.0.4] - 2019-08-20 - Windows build fixes (there was a problem with the use of ::poll that has a different name on Windows (WSAPoll)) diff --git a/ixwebsocket/IXNetSystem.cpp b/ixwebsocket/IXNetSystem.cpp index 91b17bb7..768365db 100644 --- a/ixwebsocket/IXNetSystem.cpp +++ b/ixwebsocket/IXNetSystem.cpp @@ -15,9 +15,8 @@ namespace ix WSADATA wsaData; int err; - /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + // Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h wVersionRequested = MAKEWORD(2, 2); - err = WSAStartup(wVersionRequested, &wsaData); return err == 0; @@ -30,10 +29,82 @@ namespace ix { #ifdef _WIN32 int err = WSACleanup(); - return err == 0; #else return true; #endif } + +#ifdef _WIN32 + // + // That function could 'return WSAPoll(pfd, nfds, timeout);' + // but WSAPoll is said to have weird behaviors on the internet + // (the curl folks have had problems with it). + // + // So we make it a select wrapper + // + int poll(struct pollfd *fds, nfds_t nfds, int timeout) + { + int maxfd = 0; + fd_set readfds, writefds, errorfds; + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&errorfds); + + for (nfds_t i = 0; i < nfds; ++i) + { + struct pollfd *fd = &fds[i]; + + if (fd->fd > maxfd) + { + maxfd = fd->fd; + } + if ((fd->events & POLLIN)) + { + FD_SET(fd->fd, &readfds); + } + if ((fd->events & POLLOUT)) + { + FD_SET(fd->fd, &writefds); + } + if ((fd->events & POLLERR)) + { + FD_SET(fd->fd, &errorfds); + } + } + + struct timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + int ret = select(maxfd + 1, &readfds, &writefds, &errorfds, + timeout != -1 ? &tv : NULL); + + if (ret < 0) + { + return ret; + } + + for (nfds_t i = 0; i < nfds; ++i) + { + struct pollfd *fd = &fds[i]; + fd->revents = 0; + + if (FD_ISSET(fd->fd, &readfds)) + { + fd->revents |= POLLIN; + } + if (FD_ISSET(fd->fd, &writefds)) + { + fd->revents |= POLLOUT; + } + if (FD_ISSET(fd->fd, &errorfds)) + { + fd->revents |= POLLERR; + } + } + + return ret; + } +#endif } diff --git a/ixwebsocket/IXNetSystem.h b/ixwebsocket/IXNetSystem.h index aa0ab2c2..7710fe23 100644 --- a/ixwebsocket/IXNetSystem.h +++ b/ixwebsocket/IXNetSystem.h @@ -13,22 +13,22 @@ #include #include -static inline int poll(struct pollfd *pfd, unsigned long nfds, int timeout) -{ - return WSAPoll(pfd, nfds, timeout); -} +// Define our own poll on Windows +typedef unsigned long int nfds_t; + +int poll(struct pollfd* fds, nfds_t nfds, int timeout); #else #include #include #include #include +#include #include #include #include #include #include -#include #endif namespace ix diff --git a/ixwebsocket/IXSocket.cpp b/ixwebsocket/IXSocket.cpp index dc1f5aa6..ecc90dd3 100644 --- a/ixwebsocket/IXSocket.cpp +++ b/ixwebsocket/IXSocket.cpp @@ -58,7 +58,7 @@ namespace ix // shim to fallback to select on those platforms. // See https://github.com/mpv-player/mpv/pull/5203/files for such a select wrapper. // - int nfds = 1; + nfds_t nfds = 1; struct pollfd fds[2]; fds[0].fd = sockfd; diff --git a/ws/ixcobra/IXCobraMetricsPublisher.h b/ws/ixcobra/IXCobraMetricsPublisher.h index 987de1a8..dbc13b9c 100644 --- a/ws/ixcobra/IXCobraMetricsPublisher.h +++ b/ws/ixcobra/IXCobraMetricsPublisher.h @@ -7,10 +7,10 @@ #pragma once #include "IXCobraMetricsThreadedPublisher.h" +#include #include #include #include -#include #include namespace ix