Implement poll() on systems which support it properly.

This eliminates the restriction on maximum socket descriptor number.
This commit is contained in:
Patrick Strateman
2018-09-26 21:54:52 -04:00
parent 28211a4bc9
commit 11cc491a28
3 changed files with 77 additions and 2 deletions

View File

@@ -21,6 +21,10 @@
#include <codecvt>
#endif
#ifdef USE_POLL
#include <poll.h>
#endif
#if !defined(MSG_NOSIGNAL)
#define MSG_NOSIGNAL 0
#endif
@@ -264,11 +268,19 @@ static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, c
if (!IsSelectableSocket(hSocket)) {
return IntrRecvError::NetworkError;
}
struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait));
int timeout_ms = std::min(endTime - curTime, maxWait);
#ifdef USE_POLL
struct pollfd pollfd = {};
pollfd.fd = hSocket;
pollfd.events = POLLIN | POLLOUT;
int nRet = poll(&pollfd, 1, timeout_ms);
#else
struct timeval tval = MillisToTimeval(timeout_ms);
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(hSocket, &fdset);
int nRet = select(hSocket + 1, &fdset, nullptr, nullptr, &tval);
#endif
if (nRet == SOCKET_ERROR) {
return IntrRecvError::NetworkError;
}
@@ -499,11 +511,18 @@ bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET& hSocket, i
// WSAEINVAL is here because some legacy version of winsock uses it
if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL)
{
#ifdef USE_POLL
struct pollfd pollfd = {};
pollfd.fd = hSocket;
pollfd.events = POLLIN | POLLOUT;
int nRet = poll(&pollfd, 1, nTimeout);
#else
struct timeval timeout = MillisToTimeval(nTimeout);
fd_set fdset;
FD_ZERO(&fdset);
FD_SET(hSocket, &fdset);
int nRet = select(hSocket + 1, nullptr, &fdset, nullptr, &timeout);
#endif
if (nRet == 0)
{
LogPrint(BCLog::NET, "connection to %s timeout\n", addrConnect.ToString());