Skip to content

Conversation

@vasild
Copy link
Contributor

@vasild vasild commented Apr 22, 2021

It is not possible to have a node in CConnman::vNodesDisconnected and
its reference count to be incremented - all CNode::AddRef() are done
either before the node is added to CConnman::vNodes or while holding
CConnman::cs_vNodes and the object being in CConnman::vNodes.

So, the object being in CConnman::vNodesDisconnected and its reference
count being zero means that it is not and will not start to be used by
other threads.

So, the lock of CNode::cs_vSend in CConnman::DisconnectNodes() will
always succeed and is not necessary.

Indeed all locks of CNode::cs_vSend are done either when the reference
count is >0 or under the protection of CConnman::cs_vNodes and the
node being in CConnman::vNodes.

It is not possible to have a node in `CConnman::vNodesDisconnected` and
its reference count to be incremented - all `CNode::AddRef()` are done
either before the node is added to `CConnman::vNodes` or while holding
`CConnman::cs_vNodes` and the object being in `CConnman::vNodes`.

So, the object being in `CConnman::vNodesDisconnected` and its reference
count being zero means that it is not and will not start to be used by
other threads.

So, the lock of `CNode::cs_vSend` in `CConnman::DisconnectNodes()` will
always succeed and is not necessary.

Indeed all locks of `CNode::cs_vSend` are done either when the reference
count is >0 or under the protection of `CConnman::cs_vNodes` and the
node being in `CConnman::vNodes`.
@maflcko
Copy link
Member

maflcko commented Apr 22, 2021

Concept ACK. Wanted to do the same

@vasild
Copy link
Contributor Author

vasild commented Apr 22, 2021

#19347 removed a similar check of CNode::cs_inventory. Maybe removing also the cs_vSend check was out of scope there or was overlooked? Or I am overlooking something with this PR?

cc @jnewbery

@maflcko
Copy link
Member

maflcko commented Apr 22, 2021

Checked that cs_vSend is only locked when the node is in vNodes, so any node in the disconnect pool can't fail to take the lock.

review ACK 9096b13 🏧

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

review ACK 9096b13a4764873511b65f32a005ce4738b0d81c 🏧
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUh+VAv/UH8AJG+ZvfXyiflUhYdflfmarAaklCfbP8yTP6Md4F5kUVXHLqJFQCie
63pC27Bpz33kmXJAthemyjmwYg6KocJUT/Zptd4k9AZKELqop7YNDgjHv2s0fQwU
XDWAgDaAjZYheXTwGniikRCQfFxIGiGoGVjosty6eRL+37CFz2m5EqUDfLIR/YB5
lmu/S6nsit+c+iE+mCSiFh7GHsivtXqUKPKr/RXsQCJQqFUFM4/JjbOscrnJd9m0
5kickbmQlQ9+qzvFDnitsyv5GrS1cKjalV1zUyx12IowAViTLFlYdI7nL+nMXwN5
5FtVT+ozKEt+XsPQ7NGE2pVUj03itg7+VAhczw/QUHLR20FQu/w54/bipzcq0ell
Hn5ixEgoHz+lNrJy6BMJIg+QIG3Ar+ThteSHTsa+GSHnRi+4zZgqMgtXksXJOwI8
+e/Io2Qrl4pl1d0V+MLohMQ8gDBLla+ZYksIv/Rl64HzVJcJ9LtyWP8DbPGotPNH
aKW8y7uz
=UtGP
-----END PGP SIGNATURE-----

Timestamp of file with hash 24082aa150fe7737c3faac7c37e765910fecf5202285ee81b09b4ab7c5c6f10b -

@maflcko
Copy link
Member

maflcko commented Apr 22, 2021

tested with

diff --git a/src/net.cpp b/src/net.cpp
index 5aa267f0d7..5bcc508bff 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1233,7 +1233,7 @@ void CConnman::DisconnectNodes()
                         fDelete = true;
                     }
                 }
-                if (fDelete) {
+                Assert(fDelete); {
                     vNodesDisconnected.remove(pnode);
                     DeleteNode(pnode);
                 }

@jnewbery
Copy link
Contributor

utACK 9096b13

Logic in commit message is sound. No other thread can be holding this lock if refcount is zero.

Copying the list and then iterating through the copy seems unnecessary. Perhaps for a follow up:

Details
diff --git a/src/net.cpp b/src/net.cpp
index f7d102a4df..8d53afa7f8 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1219,16 +1219,15 @@ void CConnman::DisconnectNodes()
             }
         }
     }
-    {
-        // Delete disconnected nodes
-        std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
-        for (CNode* pnode : vNodesDisconnectedCopy)
-        {
-            // Destroy the object only after other threads have stopped using it.
-            if (pnode->GetRefCount() <= 0) {
-                vNodesDisconnected.remove(pnode);
-                DeleteNode(pnode);
-            }
+
+    // Delete disconnected nodes
+    for (auto it = vNodesDisconnected.begin(); it != vNodesDisconnected.end(); ) {
+        // Destroy the object only after other threads have stopped using it.
+        if ((*it)->GetRefCount() <= 0) {
+            DeleteNode(*it);
+            it = vNodesDisconnected.erase(it);
+        } else {
+            ++it;
         }
     }
 }

@jnewbery
Copy link
Contributor

@vasild if you're interested in cleaning up locking for these objects, then you may wish to review #21563.

@maflcko maflcko merged commit 320e518 into bitcoin:master May 3, 2021
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 3, 2021
9096b13 net: remove unnecessary check of CNode::cs_vSend (Vasil Dimov)

Pull request description:

  It is not possible to have a node in `CConnman::vNodesDisconnected` and
  its reference count to be incremented - all `CNode::AddRef()` are done
  either before the node is added to `CConnman::vNodes` or while holding
  `CConnman::cs_vNodes` and the object being in `CConnman::vNodes`.

  So, the object being in `CConnman::vNodesDisconnected` and its reference
  count being zero means that it is not and will not start to be used by
  other threads.

  So, the lock of `CNode::cs_vSend` in `CConnman::DisconnectNodes()` will
  always succeed and is not necessary.

  Indeed all locks of `CNode::cs_vSend` are done either when the reference
  count is >0 or under the protection of `CConnman::cs_vNodes` and the
  node being in `CConnman::vNodes`.

ACKs for top commit:
  MarcoFalke:
    review ACK 9096b13 🏧
  jnewbery:
    utACK 9096b13

Tree-SHA512: 910899cdcdc8934642eb0c40fcece8c3b01b7e20a0b023966b9d6972db6a885cb3a9a04e9562bae14d5833967e45e2ecb3687b94d495060c3da4b1f2afb0ac8f
gwillen pushed a commit to ElementsProject/elements that referenced this pull request Jun 1, 2022
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants