From e4e22abf4c84754dd4b42f5f935e8fa7533b0cc0 Mon Sep 17 00:00:00 2001 From: dan_s Date: Mon, 23 Feb 2026 12:11:55 -0600 Subject: [PATCH] Fix Windows shutdown hang and register console ctrl handler - Remove GenerateBitcoins(false) from stop RPC handler because it calls minerThreads->join_all() which blocks the RPC thread, preventing the response from being sent back to the client. Miners are already stopped in Shutdown() so this was redundant. - Add ShutdownRequested() checks in miner peer-wait and nonce loops - Register SetConsoleCtrlHandler on Windows for clean Ctrl+C/close - Add check_and_clean_target for --linux-release builds --- build.sh | 1 + src/init.cpp | 3 +++ src/miner.cpp | 7 +++++++ src/rpc/server.cpp | 10 +++------- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/build.sh b/build.sh index 93e239379..926052caa 100755 --- a/build.sh +++ b/build.sh @@ -43,6 +43,7 @@ fi # Check for --linux-release flag (builds inside Ubuntu 20.04 container for max compatibility) if [[ "${1:-}" == "--linux-release" ]]; then + check_and_clean_target "linux-docker" shift echo "Building Linux release inside Ubuntu 20.04 Docker container..." sudo docker build -t hush-builder -f Dockerfile.build . diff --git a/src/init.cpp b/src/init.cpp index 2877dd288..62421433a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1053,6 +1053,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly signal(SIGPIPE, SIG_IGN); +#else + // On Windows, register console control handler for clean shutdown on Ctrl+C / window close + SetConsoleCtrlHandler(consoleCtrlHandler, true); #endif std::set_new_handler(new_handler_terminate); diff --git a/src/miner.cpp b/src/miner.cpp index 65f3027fe..bfd67aeb8 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -34,6 +34,7 @@ #include "RandomX/src/randomx.h" #endif #include "hash.h" +#include "init.h" #include "key_io.h" #include "main.h" #include "metrics.h" @@ -1302,6 +1303,8 @@ void static RandomXMiner() } if (!fvNodesEmpty )//&& !IsInitialBlockDownload()) break; + if (ShutdownRequested()) + throw boost::thread_interrupted(); MilliSleep(15000); //fprintf(stderr,"fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,SMART_CHAIN_SYMBOL,(int32_t)IsInitialBlockDownload()); @@ -1570,6 +1573,8 @@ void static RandomXMiner() } boost::this_thread::interruption_point(); + if (ShutdownRequested()) + throw boost::thread_interrupted(); if (vNodes.empty() && chainparams.MiningRequiresPeers()) { @@ -1702,6 +1707,8 @@ void static BitcoinMiner() } if (!fvNodesEmpty )//&& !IsInitialBlockDownload()) break; + if (ShutdownRequested()) + throw boost::thread_interrupted(); MilliSleep(15000); //fprintf(stderr,"fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,SMART_CHAIN_SYMBOL,(int32_t)IsInitialBlockDownload()); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index d98332447..3b7aed1b0 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -267,13 +267,9 @@ UniValue stop(const UniValue& params, bool fHelp, const CPubKey& mypk) "stop\n" "\nStop Hush server."); -#ifdef ENABLE_WALLET - GenerateBitcoins(false, pwalletMain, 0); -#else - GenerateBitcoins(false, 0); -#endif - - // Shutdown will take long enough that the response should get back + // Don't stop miners here — GenerateBitcoins(false) blocks on join_all() + // which prevents the RPC response from being sent back to the client. + // Miners are stopped in Shutdown() instead. StartShutdown(); if ((strncmp(SMART_CHAIN_SYMBOL, "HUSH3", 5) == 0) ) {