aboutsummaryrefslogtreecommitdiff
path: root/src/net.h
diff options
context:
space:
mode:
authorVasil Dimov <vd@FreeBSD.org>2021-04-26 16:22:07 +0200
committerVasil Dimov <vd@FreeBSD.org>2021-11-18 13:29:23 +0100
commit75e8bf55f5a014faada7712a9640dc35e8c86f15 (patch)
treee008c898e12afe42bf673a15a48de49028c0803d /src/net.h
parentb9cf505bdfade074f3d2b0473d56d2cbc2711cb3 (diff)
downloadbitcoin-75e8bf55f5a014faada7712a9640dc35e8c86f15.tar.xz
net: dedup and RAII-fy the creation of a copy of CConnman::vNodes
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 ```
Diffstat (limited to 'src/net.h')
-rw-r--r--src/net.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/net.h b/src/net.h
index 48dfb3043f..7b97b98ae5 100644
--- a/src/net.h
+++ b/src/net.h
@@ -1177,6 +1177,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;
};