@@ -207,7 +207,14 @@ void InitContext(NodeContext& node)
207207 g_shutdown.emplace ();
208208
209209 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+ };
211218}
212219
213220// ////////////////////////////////////////////////////////////////////////////
@@ -235,7 +242,7 @@ void InitContext(NodeContext& node)
235242
236243bool ShutdownRequested (node::NodeContext& node)
237244{
238- return bool {*Assert (node.shutdown )};
245+ return bool {*Assert (node.shutdown_signal )};
239246}
240247
241248#if HAVE_SYSTEM
@@ -286,7 +293,7 @@ void Shutdown(NodeContext& node)
286293
287294 StopHTTPRPC ();
288295 StopREST ();
289- StopRPC (&node );
296+ StopRPC ();
290297 StopHTTPServer ();
291298 for (const auto & client : node.chain_clients ) {
292299 client->flush ();
@@ -678,21 +685,6 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
678685 argsman.AddHiddenArgs (hidden_args);
679686}
680687
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-
696688#if HAVE_SYSTEM
697689static void StartupNotify (const ArgsManager& args)
698690{
@@ -707,7 +699,7 @@ static void StartupNotify(const ArgsManager& args)
707699static bool AppInitServers (NodeContext& node)
708700{
709701 const ArgsManager& args = *Assert (node.args );
710- if (!InitHTTPServer (*Assert (node.shutdown ))) {
702+ if (!InitHTTPServer (*Assert (node.shutdown_signal ))) {
711703 return false ;
712704 }
713705 StartRPC ();
@@ -1216,7 +1208,7 @@ static ChainstateLoadResult InitAndLoadChainstate(
12161208 };
12171209 Assert (ApplyArgsManOptions (args, blockman_opts)); // no error can happen, already checked in AppInitParameterInteraction
12181210 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);
12201212 } catch (std::exception& e) {
12211213 return {ChainstateLoadStatus::FAILURE_FATAL, strprintf (Untranslated (" Failed to initialize ChainstateManager: %s" ), e.what ())};
12221214 }
@@ -1327,7 +1319,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
13271319 constexpr uint64_t min_disk_space = 50 << 20 ; // 50 MB
13281320 if (!CheckDiskSpace (args.GetBlocksDirPath (), min_disk_space)) {
13291321 LogError (" Shutting down due to lack of disk space!\n " );
1330- if (!(* Assert (node.shutdown ))()) {
1322+ if (!(Assert (node.shutdown_request ))()) {
13311323 LogError (" Failed to send shutdown signal after disk space check\n " );
13321324 }
13331325 }
@@ -1608,8 +1600,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
16081600
16091601 // ********************************************************* Step 7: load block chain
16101602
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);
16131606
16141607 // cache size calculations
16151608 CacheSizes cache_sizes = CalculateCacheSizes (args, g_enabled_filter_types.size ());
@@ -1649,7 +1642,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
16491642 return false ;
16501643 }
16511644 do_reindex = true ;
1652- if (!Assert (node.shutdown )->reset ()) {
1645+ if (!Assert (node.shutdown_signal )->reset ()) {
16531646 LogError (" Internal error: failed to reset shutdown signal.\n " );
16541647 }
16551648 std::tie (status, error) = InitAndLoadChainstate (
@@ -1761,15 +1754,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
17611754 }
17621755 }
17631756
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-
17731757#if HAVE_SYSTEM
17741758 const std::string block_notify = args.GetArg (" -blocknotify" , " " );
17751759 if (!block_notify.empty ()) {
@@ -1794,7 +1778,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
17941778 ImportBlocks (chainman, vImportFiles);
17951779 if (args.GetBoolArg (" -stopafterblockimport" , DEFAULT_STOPAFTERBLOCKIMPORT)) {
17961780 LogPrintf (" Stopping after block import\n " );
1797- if (!(* Assert (node.shutdown ))()) {
1781+ if (!(Assert (node.shutdown_request ))()) {
17981782 LogError (" Failed to send shutdown signal after finishing block import\n " );
17991783 }
18001784 return ;
@@ -1814,15 +1798,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
18141798 });
18151799
18161800 // 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+ });
18261806 }
18271807
18281808 if (ShutdownRequested (node)) {
@@ -1831,17 +1811,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
18311811
18321812 // ********************************************************* Step 12: start node
18331813
1834- // // debug print
18351814 int64_t best_block_time{};
18361815 {
1837- LOCK (cs_main);
1816+ LOCK (chainman.GetMutex ());
1817+ const auto & tip{*Assert (chainman.ActiveTip ())};
18381818 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 ();
18411821 if (tip_info) {
18421822 tip_info->block_height = chain_active_height;
18431823 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 );
18451825 }
18461826 if (tip_info && chainman.m_best_header ) {
18471827 tip_info->header_height = chainman.m_best_header ->nHeight ;
0 commit comments