Skip to content

Commit e4bfd51

Browse files
committed
Merge #18452: qt: Fix shutdown when waitfor* cmds are called from RPC console
da73f15 qt: Fix shutdown when waitfor* cmds are called from RPC console (Hennadii Stepanov) Pull request description: On master (7eed413), if the GUI has been started with`-server=1`, `bitcoin-qt` hangs on shutdown during calling any of the `waitfor*` commands in the GUI RPC console. This PR suggests minimal changes to fix this bug. Fix #17495 ACKs for top commit: jonasschnelli: utACK da73f15 Tree-SHA512: 469f5332945a5f2c57d19336cda5df79b123ccc494aea6d58a85eb1293be52708b2b9c5bb6bc2c402a90b7b4e9e8d7ab8fe84cf201cf7ce612c9290c57e43681
2 parents f2e2c5e + da73f15 commit e4bfd51

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

src/interfaces/node.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,15 @@ class NodeImpl : public Node
8888
Interrupt(m_context);
8989
Shutdown(m_context);
9090
}
91-
void startShutdown() override { StartShutdown(); }
91+
void startShutdown() override
92+
{
93+
StartShutdown();
94+
// Stop RPC for clean shutdown if any of waitfor* commands is executed.
95+
if (gArgs.GetBoolArg("-server", false)) {
96+
InterruptRPC();
97+
StopRPC();
98+
}
99+
}
92100
bool shutdownRequested() override { return ShutdownRequested(); }
93101
void mapPort(bool use_upnp) override
94102
{

src/rpc/server.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@
1515
#include <boost/algorithm/string/split.hpp>
1616
#include <boost/signals2/signal.hpp>
1717

18+
#include <cassert>
1819
#include <memory> // for unique_ptr
20+
#include <mutex>
1921
#include <unordered_map>
2022

2123
static RecursiveMutex cs_rpcWarmup;
2224
static std::atomic<bool> g_rpc_running{false};
25+
static std::once_flag g_rpc_interrupt_flag;
26+
static std::once_flag g_rpc_stop_flag;
2327
static bool fRPCInWarmup GUARDED_BY(cs_rpcWarmup) = true;
2428
static std::string rpcWarmupStatus GUARDED_BY(cs_rpcWarmup) = "RPC server started";
2529
/* Timer-creating functions */
@@ -291,17 +295,24 @@ void StartRPC()
291295

292296
void InterruptRPC()
293297
{
294-
LogPrint(BCLog::RPC, "Interrupting RPC\n");
295-
// Interrupt e.g. running longpolls
296-
g_rpc_running = false;
298+
// This function could be called twice if the GUI has been started with -server=1.
299+
std::call_once(g_rpc_interrupt_flag, []() {
300+
LogPrint(BCLog::RPC, "Interrupting RPC\n");
301+
// Interrupt e.g. running longpolls
302+
g_rpc_running = false;
303+
});
297304
}
298305

299306
void StopRPC()
300307
{
301-
LogPrint(BCLog::RPC, "Stopping RPC\n");
302-
WITH_LOCK(g_deadline_timers_mutex, deadlineTimers.clear());
303-
DeleteAuthCookie();
304-
g_rpcSignals.Stopped();
308+
// This function could be called twice if the GUI has been started with -server=1.
309+
assert(!g_rpc_running);
310+
std::call_once(g_rpc_stop_flag, []() {
311+
LogPrint(BCLog::RPC, "Stopping RPC\n");
312+
WITH_LOCK(g_deadline_timers_mutex, deadlineTimers.clear());
313+
DeleteAuthCookie();
314+
g_rpcSignals.Stopped();
315+
});
305316
}
306317

307318
bool IsRPCRunning()

0 commit comments

Comments
 (0)