Before this change the code used to count references to CNode
objects manually via CNode::nRefCount
. Unneeded CNode
s were scheduled for deletion by putting them in CConnman::m_nodes_disconnected
and were deleted after their reference count reached zero. Deleting consists of calling PeerManager::FinalizeNode()
and destroying the CNode
object.
Replace this scheme with std::shared_ptr
. This simplifies the code and removes:
CNode::nRefCount
CNode::GetRefCount()
CNode::AddRef()
CNode::Release()
CConnman::m_nodes_disconnected
CConnman::NodesSnapshot
Now creating a snapshot of CConnman::m_nodes
is done by simply copying it (under the mutex).
Call PeerManager::FinalizeNode()
from the destructor of CNode
, which is called when the reference count reaches 0.
This removes brittle code and replaces it by a code from the standard library which is more robust. All the below are possible with the manual reference counting and not possible with shared_ptr
:
- Use an object without adding a reference to it
- Add too many references to an object, mismatch the add/remove by having more “add”
- Forget to reduce the reference count, mismatch the add/remove by having less “remove”
- Go with negative reference count by mistakenly having too many “remove”
- Destroy an object while there are references to it
There is zero learning curve for the average C++ programmer who knows how shared_ptr
works. Not so much with the manual reference counting because one has to learn about AddRef()
, Release()
, check and maintain where are they called and their relationship with m_nodes_disconnected
.
This has some history in #28222 and #10738. See below #32015 (comment) and #32015 (comment).