Skip to content

Commit cc74459

Browse files
committed
net: also wait for exceptional events in Sock::Wait()
This mimics closely `CConnman::SocketEvents()` and the underlying `poll(2)`.
1 parent e18fd47 commit cc74459

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

src/i2p.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ bool Session::Accept(Connection& conn)
150150
throw std::runtime_error("wait on socket failed");
151151
}
152152

153-
if ((occurred & Sock::RECV) == 0) {
154-
// Timeout, no incoming connections within MAX_WAIT_FOR_IO.
153+
if (occurred == 0) {
154+
// Timeout, no incoming connections or errors within MAX_WAIT_FOR_IO.
155155
continue;
156156
}
157157

src/util/sock.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occur
136136
if (fd.revents & POLLOUT) {
137137
*occurred |= SEND;
138138
}
139+
if (fd.revents & (POLLERR | POLLHUP)) {
140+
*occurred |= ERR;
141+
}
139142
}
140143

141144
return true;
@@ -146,8 +149,10 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occur
146149

147150
fd_set fdset_recv;
148151
fd_set fdset_send;
152+
fd_set fdset_err;
149153
FD_ZERO(&fdset_recv);
150154
FD_ZERO(&fdset_send);
155+
FD_ZERO(&fdset_err);
151156

152157
if (requested & RECV) {
153158
FD_SET(m_socket, &fdset_recv);
@@ -157,9 +162,11 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occur
157162
FD_SET(m_socket, &fdset_send);
158163
}
159164

165+
FD_SET(m_socket, &fdset_err);
166+
160167
timeval timeout_struct = MillisToTimeval(timeout);
161168

162-
if (select(m_socket + 1, &fdset_recv, &fdset_send, nullptr, &timeout_struct) == SOCKET_ERROR) {
169+
if (select(m_socket + 1, &fdset_recv, &fdset_send, &fdset_err, &timeout_struct) == SOCKET_ERROR) {
163170
return false;
164171
}
165172

@@ -171,6 +178,9 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occur
171178
if (FD_ISSET(m_socket, &fdset_send)) {
172179
*occurred |= SEND;
173180
}
181+
if (FD_ISSET(m_socket, &fdset_err)) {
182+
*occurred |= ERR;
183+
}
174184
}
175185

176186
return true;

src/util/sock.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,21 +130,28 @@ class Sock
130130
/**
131131
* If passed to `Wait()`, then it will wait for readiness to read from the socket.
132132
*/
133-
static constexpr Event RECV = 0b01;
133+
static constexpr Event RECV = 0b001;
134134

135135
/**
136136
* If passed to `Wait()`, then it will wait for readiness to send to the socket.
137137
*/
138-
static constexpr Event SEND = 0b10;
138+
static constexpr Event SEND = 0b010;
139+
140+
/**
141+
* Ignored if passed to `Wait()`, but could be set in the occurred events if an
142+
* exceptional condition has occurred on the socket or if it has been disconnected.
143+
*/
144+
static constexpr Event ERR = 0b100;
139145

140146
/**
141147
* Wait for readiness for input (recv) or output (send).
142148
* @param[in] timeout Wait this much for at least one of the requested events to occur.
143149
* @param[in] requested Wait for those events, bitwise-or of `RECV` and `SEND`.
144-
* @param[out] occurred If not nullptr and `true` is returned, then upon return this
145-
* indicates which of the requested events occurred. A timeout is indicated by return
146-
* value of `true` and `occurred` being set to 0.
147-
* @return true on success and false otherwise
150+
* @param[out] occurred If not nullptr and the function returns `true`, then this
151+
* indicates which of the requested events occurred (`ERR` will be added, even if
152+
* not requested, if an exceptional event occurs on the socket).
153+
* A timeout is indicated by return value of `true` and `occurred` being set to 0.
154+
* @return true on success (or timeout, if `occurred` of 0 is returned), false otherwise
148155
*/
149156
[[nodiscard]] virtual bool Wait(std::chrono::milliseconds timeout,
150157
Event requested,

0 commit comments

Comments
 (0)