mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 22:50:59 +01:00
Implement poll() on systems which support it properly.
This eliminates the restriction on maximum socket descriptor number.
This commit is contained in:
49
src/net.cpp
49
src/net.cpp
@@ -26,6 +26,10 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_POLL
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_UPNP
|
||||
#include <miniupnpc/miniupnpc.h>
|
||||
#include <miniupnpc/miniwget.h>
|
||||
@@ -33,6 +37,7 @@
|
||||
#include <miniupnpc/upnperrors.h>
|
||||
#endif
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -1307,6 +1312,49 @@ bool CConnman::GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &s
|
||||
return !recv_set.empty() || !send_set.empty() || !error_set.empty();
|
||||
}
|
||||
|
||||
#ifdef USE_POLL
|
||||
void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
|
||||
{
|
||||
std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
|
||||
if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
|
||||
interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
|
||||
return;
|
||||
}
|
||||
|
||||
std::unordered_map<SOCKET, struct pollfd> pollfds;
|
||||
for (SOCKET socket_id : recv_select_set) {
|
||||
pollfds[socket_id].fd = socket_id;
|
||||
pollfds[socket_id].events |= POLLIN;
|
||||
}
|
||||
|
||||
for (SOCKET socket_id : send_select_set) {
|
||||
pollfds[socket_id].fd = socket_id;
|
||||
pollfds[socket_id].events |= POLLOUT;
|
||||
}
|
||||
|
||||
for (SOCKET socket_id : error_select_set) {
|
||||
pollfds[socket_id].fd = socket_id;
|
||||
// These flags are ignored, but we set them for clarity
|
||||
pollfds[socket_id].events |= POLLERR|POLLHUP;
|
||||
}
|
||||
|
||||
std::vector<struct pollfd> vpollfds;
|
||||
vpollfds.reserve(pollfds.size());
|
||||
for (auto it : pollfds) {
|
||||
vpollfds.push_back(std::move(it.second));
|
||||
}
|
||||
|
||||
if (poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS) < 0) return;
|
||||
|
||||
if (interruptNet) return;
|
||||
|
||||
for (struct pollfd pollfd_entry : vpollfds) {
|
||||
if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
|
||||
if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
|
||||
if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
|
||||
{
|
||||
std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
|
||||
@@ -1380,6 +1428,7 @@ void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_s
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CConnman::SocketHandler()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user