diff options
author | Jonas Schnelli <dev@jonasschnelli.ch> | 2020-05-29 15:49:37 +0200 |
---|---|---|
committer | Jonas Schnelli <dev@jonasschnelli.ch> | 2020-05-29 15:49:46 +0200 |
commit | e4bfd51acc111c27f8a808756f88738b02388c38 (patch) | |
tree | 9f9e461cbeea74104171dfdffa2343c25fc5d9ae | |
parent | f2e2c5ebcccf8d656b850c28452e6e652934f36b (diff) | |
parent | da73f1513a637a9f347b64de66564d6cdb2541f8 (diff) | |
download | bitcoin-e4bfd51acc111c27f8a808756f88738b02388c38.tar.xz |
Merge #18452: qt: Fix shutdown when waitfor* cmds are called from RPC console
da73f1513a637a9f347b64de66564d6cdb2541f8 qt: Fix shutdown when waitfor* cmds are called from RPC console (Hennadii Stepanov)
Pull request description:
On master (7eed413e72a236b6f1475a198f7063fd24929e23), 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 da73f1513a637a9f347b64de66564d6cdb2541f8
Tree-SHA512: 469f5332945a5f2c57d19336cda5df79b123ccc494aea6d58a85eb1293be52708b2b9c5bb6bc2c402a90b7b4e9e8d7ab8fe84cf201cf7ce612c9290c57e43681
-rw-r--r-- | src/interfaces/node.cpp | 10 | ||||
-rw-r--r-- | src/rpc/server.cpp | 25 |
2 files changed, 27 insertions, 8 deletions
diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index ca1435fe60..bd1b36fea5 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -88,7 +88,15 @@ public: Interrupt(m_context); Shutdown(m_context); } - void startShutdown() override { StartShutdown(); } + void startShutdown() override + { + StartShutdown(); + // Stop RPC for clean shutdown if any of waitfor* commands is executed. + if (gArgs.GetBoolArg("-server", false)) { + InterruptRPC(); + StopRPC(); + } + } bool shutdownRequested() override { return ShutdownRequested(); } void mapPort(bool use_upnp) override { diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 99c649d15a..2a0079ac39 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -15,11 +15,15 @@ #include <boost/algorithm/string/split.hpp> #include <boost/signals2/signal.hpp> +#include <cassert> #include <memory> // for unique_ptr +#include <mutex> #include <unordered_map> static RecursiveMutex cs_rpcWarmup; static std::atomic<bool> g_rpc_running{false}; +static std::once_flag g_rpc_interrupt_flag; +static std::once_flag g_rpc_stop_flag; static bool fRPCInWarmup GUARDED_BY(cs_rpcWarmup) = true; static std::string rpcWarmupStatus GUARDED_BY(cs_rpcWarmup) = "RPC server started"; /* Timer-creating functions */ @@ -291,17 +295,24 @@ void StartRPC() void InterruptRPC() { - LogPrint(BCLog::RPC, "Interrupting RPC\n"); - // Interrupt e.g. running longpolls - g_rpc_running = false; + // This function could be called twice if the GUI has been started with -server=1. + std::call_once(g_rpc_interrupt_flag, []() { + LogPrint(BCLog::RPC, "Interrupting RPC\n"); + // Interrupt e.g. running longpolls + g_rpc_running = false; + }); } void StopRPC() { - LogPrint(BCLog::RPC, "Stopping RPC\n"); - WITH_LOCK(g_deadline_timers_mutex, deadlineTimers.clear()); - DeleteAuthCookie(); - g_rpcSignals.Stopped(); + // This function could be called twice if the GUI has been started with -server=1. + assert(!g_rpc_running); + std::call_once(g_rpc_stop_flag, []() { + LogPrint(BCLog::RPC, "Stopping RPC\n"); + WITH_LOCK(g_deadline_timers_mutex, deadlineTimers.clear()); + DeleteAuthCookie(); + g_rpcSignals.Stopped(); + }); } bool IsRPCRunning() |