|
|
|
@ -200,20 +200,7 @@ void Shutdown(NodeContext& node)
|
|
|
|
|
// Because these depend on each-other, we make sure that neither can be
|
|
|
|
|
// using the other before destroying them.
|
|
|
|
|
if (node.peerman) UnregisterValidationInterface(node.peerman.get());
|
|
|
|
|
// Follow the lock order requirements:
|
|
|
|
|
// * CheckForStaleTipAndEvictPeers locks cs_main before indirectly calling GetExtraFullOutboundCount
|
|
|
|
|
// which locks cs_vNodes.
|
|
|
|
|
// * ProcessMessage locks cs_main and g_cs_orphans before indirectly calling ForEachNode which
|
|
|
|
|
// locks cs_vNodes.
|
|
|
|
|
// * CConnman::Stop calls DeleteNode, which calls FinalizeNode, which locks cs_main and calls
|
|
|
|
|
// EraseOrphansFor, which locks g_cs_orphans.
|
|
|
|
|
//
|
|
|
|
|
// Thus the implicit locking order requirement is: (1) cs_main, (2) g_cs_orphans, (3) cs_vNodes.
|
|
|
|
|
if (node.connman) {
|
|
|
|
|
node.connman->StopThreads();
|
|
|
|
|
LOCK2(::cs_main, ::g_cs_orphans);
|
|
|
|
|
node.connman->StopNodes();
|
|
|
|
|
}
|
|
|
|
|
if (node.connman) node.connman->Stop();
|
|
|
|
|
|
|
|
|
|
StopTorControl();
|
|
|
|
|
|
|
|
|
|