diff --git a/src/linux_tcp/poll.h b/src/linux_tcp/poll.h index 6839c29..70c3aa0 100644 --- a/src/linux_tcp/poll.h +++ b/src/linux_tcp/poll.h @@ -11,6 +11,11 @@ */ #pragma once +/** + * Includes + */ +#include + /** * Begin of namespace */ @@ -26,7 +31,7 @@ private: * Set with just one filedescriptor * @var fd_set */ - fd_set _set; + pollfd _fd; /** * The socket filedescriptor @@ -39,13 +44,10 @@ public: * Constructor * @param fd the filedescriptor that we're waiting on */ - Poll(int fd) : _socket(fd) + Poll(int fd) { - // initialize the set - FD_ZERO(&_set); - - // add the one socket - FD_SET(_socket, &_set); + // set the fd + _fd.fd = fd; } /** @@ -60,66 +62,45 @@ public: virtual ~Poll() = default; /** - * Wait until the filedescriptor becomes readable - * @param block block until readable + * Check if a file descriptor is readable. * @return bool */ - bool readable(bool block) - { - // wait for the socket - if (block) return select(_socket + 1, &_set, nullptr, nullptr, nullptr) > 0; - - // we do not want to block, so we use a small timeout - struct timeval timeout; - - // no timeout at all - timeout.tv_sec = timeout.tv_usec = 0; - - // no timeout at all - return select(_socket + 1, &_set, nullptr, nullptr, &timeout) > 0; + bool readable() + { + // check for readable + _fd.events = POLLIN; + _fd.revents = 0; + + // poll the fd with no timeout + return poll(&_fd, 1, 0) > 0; } /** * Wait until the filedescriptor becomes writable - * @param block block until readable * @return bool */ - bool writable(bool block) + bool writable() { - // wait for the socket - if (block) return select(_socket + 1, nullptr, &_set, nullptr, nullptr) > 0; + // check for readable + _fd.events = POLLOUT; + _fd.revents = 0; - // we do not want to block, so we use a small timeout - struct timeval timeout; - - // no timeout at all - timeout.tv_sec = timeout.tv_usec = 0; - - // no timeout at all - return select(_socket + 1, nullptr, &_set, nullptr, &timeout) > 0; + // poll the fd with no timeout + return poll(&_fd, 1, 0) > 0; } /** * Wait until a filedescriptor becomes active (readable or writable) - * @param block block until readable * @return bool */ - bool active(bool block) + bool active() { - // accommodate restrict qualifier on fd_set params - fd_set set2 = _set; + // check for readable + _fd.events = POLLIN | POLLOUT; + _fd.revents = 0; - // wait for the socket - if (block) return select(_socket + 1, &_set, &set2, nullptr, nullptr) > 0; - - // we do not want to block, so we use a small timeout - struct timeval timeout; - - // no timeout at all - timeout.tv_sec = timeout.tv_usec = 0; - - // no timeout at all - return select(_socket + 1, &_set, &set2, nullptr, &timeout) > 0; + // poll the fd with no timeout + return poll(&_fd, 1, 0) > 0; } }; diff --git a/src/linux_tcp/sslconnected.h b/src/linux_tcp/sslconnected.h index f8d8d72..d71d279 100644 --- a/src/linux_tcp/sslconnected.h +++ b/src/linux_tcp/sslconnected.h @@ -220,8 +220,8 @@ private: // object to poll a socket Poll poll(_socket); - // wait until socket is readable, but do not block - return poll.readable(false); + // check if socket is readable + return poll.readable(); } /** @@ -233,8 +233,8 @@ private: // object to poll a socket Poll poll(_socket); - // wait until socket is writable, but do not block - return poll.writable(false); + // check if socket is writable + return poll.writable(); } /** diff --git a/src/linux_tcp/tcpresolver.h b/src/linux_tcp/tcpresolver.h index 6ad9f9a..b5c2fa4 100644 --- a/src/linux_tcp/tcpresolver.h +++ b/src/linux_tcp/tcpresolver.h @@ -24,6 +24,7 @@ #include "sslhandshake.h" #include #include +#include /** * Set up namespace @@ -99,8 +100,8 @@ private: // get address info AddressInfo addresses(_hostname.data(), _port); - // an fdset to monitor for writability - fd_set writeset; + // the pollfd structure, needed for poll() + pollfd fd; // iterate over the addresses for (size_t i = 0; i < addresses.size(); ++i) @@ -117,17 +118,13 @@ private: // try to connect non-blocking if (connect(_socket, addresses[i]->ai_addr, addresses[i]->ai_addrlen) == 0) break; - // we set the timeout to a timeout, with 5 seconds as the default - struct timeval timeout{_timeout,0}; - - // reset the fdset - FD_ZERO(&writeset); - - // set the fd to monitor for writing - FD_SET(_socket, &writeset); - - // perform a select, wait for something to happen on one of the fds - int ret = select(_socket + 1, nullptr, &writeset, nullptr, &timeout); + // set the struct members + fd.fd = _socket; + fd.events = POLLOUT; + fd.revents = 0; + + // perform the poll, with a very long time to allow the event to occur + int ret = poll(&fd, 1, _timeout * 1000); // log the error for the time being if (ret == 0) _error = "connection timed out";