mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 14:38:29 +01:00
Merge bitcoin/bitcoin#21943: Dedup and RAII-fy the creation of a copy of CConnman::vNodes
f52b6b2d9fnet: split CConnman::SocketHandler() (Vasil Dimov)c7eb19ec83style: remove unnecessary braces (Vasil Dimov)664ac22c53net: keep reference to each node during socket wait (Vasil Dimov)75e8bf55f5net: dedup and RAII-fy the creation of a copy of CConnman::vNodes (Vasil Dimov) Pull request description: _This is a piece of https://github.com/bitcoin/bitcoin/pull/21878, chopped off to ease review._ The following pattern was duplicated in CConnman: ```cpp lock create a copy of vNodes, add a reference to each one unlock ... use the copy ... lock release each node from the copy unlock ``` Put that code in a RAII helper that reduces it to: ```cpp create snapshot "snap" ... use the copy ... // release happens when "snap" goes out of scope ACKs for top commit: jonatack: ACKf52b6b2d9fchanges since last review are reordered commits, removing an unneeded local variable, and code formatting and documentation improvements LarryRuane: code review ACKf52b6b2d9fpromag: Code review ACKf52b6b2d9f, only format changes and comment tweaks since last review. Tree-SHA512: 5ead7b4c641ebe5b215e7baeb7bc0cdab2a588b2871d9a343a1d518535c55c0353d4e46de663f41513cdcc79262938ccea3232f6d5166570fc2230286c985f68
This commit is contained in:
89
src/net.h
89
src/net.h
@@ -983,9 +983,57 @@ private:
|
||||
void NotifyNumConnectionsChanged();
|
||||
/** Return true if the peer is inactive and should be disconnected. */
|
||||
bool InactivityCheck(const CNode& node) const;
|
||||
bool GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set);
|
||||
void SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set);
|
||||
|
||||
/**
|
||||
* Generate a collection of sockets to check for IO readiness.
|
||||
* @param[in] nodes Select from these nodes' sockets.
|
||||
* @param[out] recv_set Sockets to check for read readiness.
|
||||
* @param[out] send_set Sockets to check for write readiness.
|
||||
* @param[out] error_set Sockets to check for errors.
|
||||
* @return true if at least one socket is to be checked (the returned set is not empty)
|
||||
*/
|
||||
bool GenerateSelectSet(const std::vector<CNode*>& nodes,
|
||||
std::set<SOCKET>& recv_set,
|
||||
std::set<SOCKET>& send_set,
|
||||
std::set<SOCKET>& error_set);
|
||||
|
||||
/**
|
||||
* Check which sockets are ready for IO.
|
||||
* @param[in] nodes Select from these nodes' sockets.
|
||||
* @param[out] recv_set Sockets which are ready for read.
|
||||
* @param[out] send_set Sockets which are ready for write.
|
||||
* @param[out] error_set Sockets which have errors.
|
||||
* This calls `GenerateSelectSet()` to gather a list of sockets to check.
|
||||
*/
|
||||
void SocketEvents(const std::vector<CNode*>& nodes,
|
||||
std::set<SOCKET>& recv_set,
|
||||
std::set<SOCKET>& send_set,
|
||||
std::set<SOCKET>& error_set);
|
||||
|
||||
/**
|
||||
* Check connected and listening sockets for IO readiness and process them accordingly.
|
||||
*/
|
||||
void SocketHandler();
|
||||
|
||||
/**
|
||||
* Do the read/write for connected sockets that are ready for IO.
|
||||
* @param[in] nodes Nodes to process. The socket of each node is checked against
|
||||
* `recv_set`, `send_set` and `error_set`.
|
||||
* @param[in] recv_set Sockets that are ready for read.
|
||||
* @param[in] send_set Sockets that are ready for send.
|
||||
* @param[in] error_set Sockets that have an exceptional condition (error).
|
||||
*/
|
||||
void SocketHandlerConnected(const std::vector<CNode*>& nodes,
|
||||
const std::set<SOCKET>& recv_set,
|
||||
const std::set<SOCKET>& send_set,
|
||||
const std::set<SOCKET>& error_set);
|
||||
|
||||
/**
|
||||
* Accept incoming connections, one from each read-ready listening socket.
|
||||
* @param[in] recv_set Sockets that are ready for read.
|
||||
*/
|
||||
void SocketHandlerListening(const std::set<SOCKET>& recv_set);
|
||||
|
||||
void ThreadSocketHandler();
|
||||
void ThreadDNSAddressSeed();
|
||||
|
||||
@@ -1177,6 +1225,43 @@ private:
|
||||
*/
|
||||
std::vector<CService> m_onion_binds;
|
||||
|
||||
/**
|
||||
* RAII helper to atomically create a copy of `vNodes` and add a reference
|
||||
* to each of the nodes. The nodes are released when this object is destroyed.
|
||||
*/
|
||||
class NodesSnapshot
|
||||
{
|
||||
public:
|
||||
explicit NodesSnapshot(const CConnman& connman, bool shuffle)
|
||||
{
|
||||
{
|
||||
LOCK(connman.cs_vNodes);
|
||||
m_nodes_copy = connman.vNodes;
|
||||
for (auto& node : m_nodes_copy) {
|
||||
node->AddRef();
|
||||
}
|
||||
}
|
||||
if (shuffle) {
|
||||
Shuffle(m_nodes_copy.begin(), m_nodes_copy.end(), FastRandomContext{});
|
||||
}
|
||||
}
|
||||
|
||||
~NodesSnapshot()
|
||||
{
|
||||
for (auto& node : m_nodes_copy) {
|
||||
node->Release();
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<CNode*>& Nodes() const
|
||||
{
|
||||
return m_nodes_copy;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<CNode*> m_nodes_copy;
|
||||
};
|
||||
|
||||
friend struct CConnmanTest;
|
||||
friend struct ConnmanTestMsg;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user