aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasil Dimov <vd@FreeBSD.org>2021-02-12 14:05:53 +0100
committerVasil Dimov <vd@FreeBSD.org>2021-03-01 13:22:18 +0100
commitea1845315a109eb105113cb5fbb6f869e1cf010c (patch)
tree9399f7d888fe98a400aea3f5350214364c55ace7
parent78fdfbea666201b25919dd67454eb04d6a34326f (diff)
net: extend Sock::Wait() to report a timeout
Previously `Sock::Wait()` would not have signaled to the caller whether a timeout or one of the requested events occurred since that was not needed by any of the callers. Such functionality will be needed in the I2P implementation, thus extend the `Sock::Wait()` method.
-rw-r--r--src/util/sock.cpp34
-rw-r--r--src/util/sock.h7
2 files changed, 37 insertions, 4 deletions
diff --git a/src/util/sock.cpp b/src/util/sock.cpp
index 4c65b5b680..d8fd9d4138 100644
--- a/src/util/sock.cpp
+++ b/src/util/sock.cpp
@@ -59,7 +59,7 @@ ssize_t Sock::Recv(void* buf, size_t len, int flags) const
return recv(m_socket, static_cast<char*>(buf), len, flags);
}
-bool Sock::Wait(std::chrono::milliseconds timeout, Event requested) const
+bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
{
#ifdef USE_POLL
pollfd fd;
@@ -72,7 +72,21 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested) const
fd.events |= POLLOUT;
}
- return poll(&fd, 1, count_milliseconds(timeout)) != SOCKET_ERROR;
+ if (poll(&fd, 1, count_milliseconds(timeout)) == SOCKET_ERROR) {
+ return false;
+ }
+
+ if (occurred != nullptr) {
+ *occurred = 0;
+ if (fd.revents & POLLIN) {
+ *occurred |= RECV;
+ }
+ if (fd.revents & POLLOUT) {
+ *occurred |= SEND;
+ }
+ }
+
+ return true;
#else
if (!IsSelectableSocket(m_socket)) {
return false;
@@ -93,7 +107,21 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested) const
timeval timeout_struct = MillisToTimeval(timeout);
- return select(m_socket + 1, &fdset_recv, &fdset_send, nullptr, &timeout_struct) != SOCKET_ERROR;
+ if (select(m_socket + 1, &fdset_recv, &fdset_send, nullptr, &timeout_struct) == SOCKET_ERROR) {
+ return false;
+ }
+
+ if (occurred != nullptr) {
+ *occurred = 0;
+ if (FD_ISSET(m_socket, &fdset_recv)) {
+ *occurred |= RECV;
+ }
+ if (FD_ISSET(m_socket, &fdset_send)) {
+ *occurred |= SEND;
+ }
+ }
+
+ return true;
#endif /* USE_POLL */
}
diff --git a/src/util/sock.h b/src/util/sock.h
index 23c3c35dad..2d9cac14af 100644
--- a/src/util/sock.h
+++ b/src/util/sock.h
@@ -105,9 +105,14 @@ public:
* Wait for readiness for input (recv) or output (send).
* @param[in] timeout Wait this much for at least one of the requested events to occur.
* @param[in] requested Wait for those events, bitwise-or of `RECV` and `SEND`.
+ * @param[out] occurred If not nullptr and `true` is returned, then upon return this
+ * indicates which of the requested events occurred. A timeout is indicated by return
+ * value of `true` and `occurred` being set to 0.
* @return true on success and false otherwise
*/
- virtual bool Wait(std::chrono::milliseconds timeout, Event requested) const;
+ virtual bool Wait(std::chrono::milliseconds timeout,
+ Event requested,
+ Event* occurred = nullptr) const;
private:
/**