mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 18:53:23 -03:00
net: also wait for exceptional events in Sock::Wait()
This mimics closely `CConnman::SocketEvents()` and the underlying `poll(2)`.
This commit is contained in:
parent
e18fd4763e
commit
cc74459768
3 changed files with 26 additions and 9 deletions
|
@ -150,8 +150,8 @@ bool Session::Accept(Connection& conn)
|
||||||
throw std::runtime_error("wait on socket failed");
|
throw std::runtime_error("wait on socket failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((occurred & Sock::RECV) == 0) {
|
if (occurred == 0) {
|
||||||
// Timeout, no incoming connections within MAX_WAIT_FOR_IO.
|
// Timeout, no incoming connections or errors within MAX_WAIT_FOR_IO.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,9 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occur
|
||||||
if (fd.revents & POLLOUT) {
|
if (fd.revents & POLLOUT) {
|
||||||
*occurred |= SEND;
|
*occurred |= SEND;
|
||||||
}
|
}
|
||||||
|
if (fd.revents & (POLLERR | POLLHUP)) {
|
||||||
|
*occurred |= ERR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -146,8 +149,10 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occur
|
||||||
|
|
||||||
fd_set fdset_recv;
|
fd_set fdset_recv;
|
||||||
fd_set fdset_send;
|
fd_set fdset_send;
|
||||||
|
fd_set fdset_err;
|
||||||
FD_ZERO(&fdset_recv);
|
FD_ZERO(&fdset_recv);
|
||||||
FD_ZERO(&fdset_send);
|
FD_ZERO(&fdset_send);
|
||||||
|
FD_ZERO(&fdset_err);
|
||||||
|
|
||||||
if (requested & RECV) {
|
if (requested & RECV) {
|
||||||
FD_SET(m_socket, &fdset_recv);
|
FD_SET(m_socket, &fdset_recv);
|
||||||
|
@ -157,9 +162,11 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occur
|
||||||
FD_SET(m_socket, &fdset_send);
|
FD_SET(m_socket, &fdset_send);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FD_SET(m_socket, &fdset_err);
|
||||||
|
|
||||||
timeval timeout_struct = MillisToTimeval(timeout);
|
timeval timeout_struct = MillisToTimeval(timeout);
|
||||||
|
|
||||||
if (select(m_socket + 1, &fdset_recv, &fdset_send, nullptr, &timeout_struct) == SOCKET_ERROR) {
|
if (select(m_socket + 1, &fdset_recv, &fdset_send, &fdset_err, &timeout_struct) == SOCKET_ERROR) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +178,9 @@ bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occur
|
||||||
if (FD_ISSET(m_socket, &fdset_send)) {
|
if (FD_ISSET(m_socket, &fdset_send)) {
|
||||||
*occurred |= SEND;
|
*occurred |= SEND;
|
||||||
}
|
}
|
||||||
|
if (FD_ISSET(m_socket, &fdset_err)) {
|
||||||
|
*occurred |= ERR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -130,21 +130,28 @@ public:
|
||||||
/**
|
/**
|
||||||
* If passed to `Wait()`, then it will wait for readiness to read from the socket.
|
* If passed to `Wait()`, then it will wait for readiness to read from the socket.
|
||||||
*/
|
*/
|
||||||
static constexpr Event RECV = 0b01;
|
static constexpr Event RECV = 0b001;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If passed to `Wait()`, then it will wait for readiness to send to the socket.
|
* If passed to `Wait()`, then it will wait for readiness to send to the socket.
|
||||||
*/
|
*/
|
||||||
static constexpr Event SEND = 0b10;
|
static constexpr Event SEND = 0b010;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignored if passed to `Wait()`, but could be set in the occurred events if an
|
||||||
|
* exceptional condition has occurred on the socket or if it has been disconnected.
|
||||||
|
*/
|
||||||
|
static constexpr Event ERR = 0b100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for readiness for input (recv) or output (send).
|
* 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] 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[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
|
* @param[out] occurred If not nullptr and the function returns `true`, then this
|
||||||
* indicates which of the requested events occurred. A timeout is indicated by return
|
* indicates which of the requested events occurred (`ERR` will be added, even if
|
||||||
* value of `true` and `occurred` being set to 0.
|
* not requested, if an exceptional event occurs on the socket).
|
||||||
* @return true on success and false otherwise
|
* A timeout is indicated by return value of `true` and `occurred` being set to 0.
|
||||||
|
* @return true on success (or timeout, if `occurred` of 0 is returned), false otherwise
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] virtual bool Wait(std::chrono::milliseconds timeout,
|
[[nodiscard]] virtual bool Wait(std::chrono::milliseconds timeout,
|
||||||
Event requested,
|
Event requested,
|
||||||
|
|
Loading…
Add table
Reference in a new issue