Changeset View
Changeset View
Standalone View
Standalone View
src/init.cpp
Show First 20 Lines • Show All 206 Lines • ▼ Show 20 Lines | if (g_avalanche) { | ||||
g_avalanche->stopEventLoop(); | g_avalanche->stopEventLoop(); | ||||
} | } | ||||
// Because these depend on each-other, we make sure that neither can be | // Because these depend on each-other, we make sure that neither can be | ||||
// using the other before destroying them. | // using the other before destroying them. | ||||
if (node.peer_logic) { | if (node.peer_logic) { | ||||
UnregisterValidationInterface(node.peer_logic.get()); | UnregisterValidationInterface(node.peer_logic.get()); | ||||
} | } | ||||
// Follow the lock order requirements: | |||||
// * CheckForStaleTipAndEvictPeers locks cs_main before indirectly calling | |||||
// GetExtraOutboundCount 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) { | if (node.connman) { | ||||
node.connman->Stop(); | node.connman->StopThreads(); | ||||
LOCK2(::cs_main, ::g_cs_orphans); | |||||
node.connman->StopNodes(); | |||||
} | } | ||||
if (g_txindex) { | if (g_txindex) { | ||||
g_txindex->Stop(); | g_txindex->Stop(); | ||||
} | } | ||||
ForEachBlockFilterIndex([](BlockFilterIndex &index) { index.Stop(); }); | ForEachBlockFilterIndex([](BlockFilterIndex &index) { index.Stop(); }); | ||||
StopTorControl(); | StopTorControl(); | ||||
▲ Show 20 Lines • Show All 2,596 Lines • Show Last 20 Lines |