@@ -207,7 +207,14 @@ void InitContext(NodeContext& node)
207
207
g_shutdown.emplace ();
208
208
209
209
node.args = &gArgs ;
210
- node.shutdown = &*g_shutdown;
210
+ node.shutdown_signal = &*g_shutdown;
211
+ node.shutdown_request = [&node] {
212
+ assert (node.shutdown_signal );
213
+ if (!(*node.shutdown_signal )()) return false ;
214
+ // Wake any threads that may be waiting for the tip to change.
215
+ if (node.notifications ) WITH_LOCK (node.notifications ->m_tip_block_mutex , node.notifications ->m_tip_block_cv .notify_all ());
216
+ return true ;
217
+ };
211
218
}
212
219
213
220
// ////////////////////////////////////////////////////////////////////////////
@@ -235,7 +242,7 @@ void InitContext(NodeContext& node)
235
242
236
243
bool ShutdownRequested (node::NodeContext& node)
237
244
{
238
- return bool {*Assert (node.shutdown )};
245
+ return bool {*Assert (node.shutdown_signal )};
239
246
}
240
247
241
248
#if HAVE_SYSTEM
@@ -286,7 +293,7 @@ void Shutdown(NodeContext& node)
286
293
287
294
StopHTTPRPC ();
288
295
StopREST ();
289
- StopRPC (&node );
296
+ StopRPC ();
290
297
StopHTTPServer ();
291
298
for (const auto & client : node.chain_clients ) {
292
299
client->flush ();
@@ -678,21 +685,6 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
678
685
argsman.AddHiddenArgs (hidden_args);
679
686
}
680
687
681
- static bool fHaveGenesis = false ;
682
- static GlobalMutex g_genesis_wait_mutex;
683
- static std::condition_variable g_genesis_wait_cv;
684
-
685
- static void BlockNotifyGenesisWait (const CBlockIndex* pBlockIndex)
686
- {
687
- if (pBlockIndex != nullptr ) {
688
- {
689
- LOCK (g_genesis_wait_mutex);
690
- fHaveGenesis = true ;
691
- }
692
- g_genesis_wait_cv.notify_all ();
693
- }
694
- }
695
-
696
688
#if HAVE_SYSTEM
697
689
static void StartupNotify (const ArgsManager& args)
698
690
{
@@ -707,7 +699,7 @@ static void StartupNotify(const ArgsManager& args)
707
699
static bool AppInitServers (NodeContext& node)
708
700
{
709
701
const ArgsManager& args = *Assert (node.args );
710
- if (!InitHTTPServer (*Assert (node.shutdown ))) {
702
+ if (!InitHTTPServer (*Assert (node.shutdown_signal ))) {
711
703
return false ;
712
704
}
713
705
StartRPC ();
@@ -1216,7 +1208,7 @@ static ChainstateLoadResult InitAndLoadChainstate(
1216
1208
};
1217
1209
Assert (ApplyArgsManOptions (args, blockman_opts)); // no error can happen, already checked in AppInitParameterInteraction
1218
1210
try {
1219
- node.chainman = std::make_unique<ChainstateManager>(*Assert (node.shutdown ), chainman_opts, blockman_opts);
1211
+ node.chainman = std::make_unique<ChainstateManager>(*Assert (node.shutdown_signal ), chainman_opts, blockman_opts);
1220
1212
} catch (std::exception & e) {
1221
1213
return {ChainstateLoadStatus::FAILURE_FATAL, strprintf (Untranslated (" Failed to initialize ChainstateManager: %s" ), e.what ())};
1222
1214
}
@@ -1327,7 +1319,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
1327
1319
constexpr uint64_t min_disk_space = 50 << 20 ; // 50 MB
1328
1320
if (!CheckDiskSpace (args.GetBlocksDirPath (), min_disk_space)) {
1329
1321
LogError (" Shutting down due to lack of disk space!\n " );
1330
- if (!(* Assert (node.shutdown ))()) {
1322
+ if (!(Assert (node.shutdown_request ))()) {
1331
1323
LogError (" Failed to send shutdown signal after disk space check\n " );
1332
1324
}
1333
1325
}
@@ -1608,8 +1600,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
1608
1600
1609
1601
// ********************************************************* Step 7: load block chain
1610
1602
1611
- node.notifications = std::make_unique<KernelNotifications>(*Assert (node.shutdown ), node.exit_status , *Assert (node.warnings ));
1612
- ReadNotificationArgs (args, *node.notifications );
1603
+ node.notifications = std::make_unique<KernelNotifications>(Assert (node.shutdown_request ), node.exit_status , *Assert (node.warnings ));
1604
+ auto & kernel_notifications{*node.notifications };
1605
+ ReadNotificationArgs (args, kernel_notifications);
1613
1606
1614
1607
// cache size calculations
1615
1608
CacheSizes cache_sizes = CalculateCacheSizes (args, g_enabled_filter_types.size ());
@@ -1649,7 +1642,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
1649
1642
return false ;
1650
1643
}
1651
1644
do_reindex = true ;
1652
- if (!Assert (node.shutdown )->reset ()) {
1645
+ if (!Assert (node.shutdown_signal )->reset ()) {
1653
1646
LogError (" Internal error: failed to reset shutdown signal.\n " );
1654
1647
}
1655
1648
std::tie (status, error) = InitAndLoadChainstate (
@@ -1761,15 +1754,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
1761
1754
}
1762
1755
}
1763
1756
1764
- // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
1765
- // No locking, as this happens before any background thread is started.
1766
- boost::signals2::connection block_notify_genesis_wait_connection;
1767
- if (WITH_LOCK (chainman.GetMutex (), return chainman.ActiveChain ().Tip () == nullptr )) {
1768
- block_notify_genesis_wait_connection = uiInterface.NotifyBlockTip_connect (std::bind (BlockNotifyGenesisWait, std::placeholders::_2));
1769
- } else {
1770
- fHaveGenesis = true ;
1771
- }
1772
-
1773
1757
#if HAVE_SYSTEM
1774
1758
const std::string block_notify = args.GetArg (" -blocknotify" , " " );
1775
1759
if (!block_notify.empty ()) {
@@ -1794,7 +1778,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
1794
1778
ImportBlocks (chainman, vImportFiles);
1795
1779
if (args.GetBoolArg (" -stopafterblockimport" , DEFAULT_STOPAFTERBLOCKIMPORT)) {
1796
1780
LogPrintf (" Stopping after block import\n " );
1797
- if (!(* Assert (node.shutdown ))()) {
1781
+ if (!(Assert (node.shutdown_request ))()) {
1798
1782
LogError (" Failed to send shutdown signal after finishing block import\n " );
1799
1783
}
1800
1784
return ;
@@ -1814,15 +1798,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
1814
1798
});
1815
1799
1816
1800
// Wait for genesis block to be processed
1817
- {
1818
- WAIT_LOCK (g_genesis_wait_mutex, lock);
1819
- // We previously could hang here if shutdown was requested prior to
1820
- // ImportBlocks getting started, so instead we just wait on a timer to
1821
- // check ShutdownRequested() regularly.
1822
- while (!fHaveGenesis && !ShutdownRequested (node)) {
1823
- g_genesis_wait_cv.wait_for (lock, std::chrono::milliseconds (500 ));
1824
- }
1825
- block_notify_genesis_wait_connection.disconnect ();
1801
+ if (WITH_LOCK (chainman.GetMutex (), return chainman.ActiveTip () == nullptr )) {
1802
+ WAIT_LOCK (kernel_notifications.m_tip_block_mutex , lock);
1803
+ kernel_notifications.m_tip_block_cv .wait (lock, [&]() EXCLUSIVE_LOCKS_REQUIRED (kernel_notifications.m_tip_block_mutex ) {
1804
+ return !kernel_notifications.m_tip_block .IsNull () || ShutdownRequested (node);
1805
+ });
1826
1806
}
1827
1807
1828
1808
if (ShutdownRequested (node)) {
@@ -1831,17 +1811,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
1831
1811
1832
1812
// ********************************************************* Step 12: start node
1833
1813
1834
- // // debug print
1835
1814
int64_t best_block_time{};
1836
1815
{
1837
- LOCK (cs_main);
1816
+ LOCK (chainman.GetMutex ());
1817
+ const auto & tip{*Assert (chainman.ActiveTip ())};
1838
1818
LogPrintf (" block tree size = %u\n " , chainman.BlockIndex ().size ());
1839
- chain_active_height = chainman. ActiveChain (). Height () ;
1840
- best_block_time = chainman. ActiveChain (). Tip () ? chainman. ActiveChain (). Tip ()-> GetBlockTime () : chainman. GetParams (). GenesisBlock () .GetBlockTime ();
1819
+ chain_active_height = tip. nHeight ;
1820
+ best_block_time = tip .GetBlockTime ();
1841
1821
if (tip_info) {
1842
1822
tip_info->block_height = chain_active_height;
1843
1823
tip_info->block_time = best_block_time;
1844
- tip_info->verification_progress = GuessVerificationProgress (chainman.GetParams ().TxData (), chainman. ActiveChain (). Tip () );
1824
+ tip_info->verification_progress = GuessVerificationProgress (chainman.GetParams ().TxData (), &tip );
1845
1825
}
1846
1826
if (tip_info && chainman.m_best_header ) {
1847
1827
tip_info->header_height = chainman.m_best_header ->nHeight ;
0 commit comments