Skip to content

Commit c065bcd

Browse files
ryanofskyfanquake
authored andcommitted
init: Signal m_tip_block_cv on Ctrl-C
Signal m_tip_block_cv when Ctrl-C is pressed or SIGTERM is received, the same way it is currently signalled when the `stop` RPC is called. This lets RPC calls like `waitforblockheight` and IPC calls like `waitTipChanged` be interrupted, instead of waiting for their original timeouts and delaying shutdown. Historical notes: - The behavior where `stop` RPC signals `m_tip_block_cv`, but CTRL-C does not, has been around since the condition variable was introduced in #30409 (7eccdaf). - The signaling was later moved without changing behavior in #30967 (5ca28ef). This commit moves it again to the Interrupt() function, which is probably the place it should have been added initially, so it works for Ctrl-C shutdowns as well as `stop` shutdowns. - A Qt shutdown bug calling wait methods was fixed previously in #18452 (da73f15), and this change updates that fix to avoid the hang happening again in Qt. Github-Pull: #33511 Rebased-From: c25a5e6
1 parent 6983c7d commit c065bcd

File tree

3 files changed

+8
-19
lines changed

3 files changed

+8
-19
lines changed

src/init.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,6 @@ void InitContext(NodeContext& node)
215215
node.shutdown_request = [&node] {
216216
assert(node.shutdown_signal);
217217
if (!(*node.shutdown_signal)()) return false;
218-
// Wake any threads that may be waiting for the tip to change.
219-
if (node.notifications) WITH_LOCK(node.notifications->m_tip_block_mutex, node.notifications->m_tip_block_cv.notify_all());
220218
return true;
221219
};
222220
}
@@ -267,6 +265,8 @@ void Interrupt(NodeContext& node)
267265
#if HAVE_SYSTEM
268266
ShutdownNotify(*node.args);
269267
#endif
268+
// Wake any threads that may be waiting for the tip to change.
269+
if (node.notifications) WITH_LOCK(node.notifications->m_tip_block_mutex, node.notifications->m_tip_block_cv.notify_all());
270270
InterruptHTTPServer();
271271
InterruptHTTPRPC();
272272
InterruptRPC();

src/node/interfaces.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ class NodeImpl : public Node
132132
}
133133
void appShutdown() override
134134
{
135-
Interrupt(*m_context);
136135
Shutdown(*m_context);
137136
}
138137
void startShutdown() override
@@ -141,12 +140,7 @@ class NodeImpl : public Node
141140
if (!(Assert(ctx.shutdown_request))()) {
142141
LogError("Failed to send shutdown signal\n");
143142
}
144-
145-
// Stop RPC for clean shutdown if any of waitfor* commands is executed.
146-
if (args().GetBoolArg("-server", false)) {
147-
InterruptRPC();
148-
StopRPC();
149-
}
143+
Interrupt(*m_context);
150144
}
151145
bool shutdownRequested() override { return ShutdownRequested(*Assert(m_context)); };
152146
bool isSettingIgnored(const std::string& name) override

test/functional/feature_init.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import subprocess
1313
import time
1414

15-
from test_framework.authproxy import JSONRPCException
1615
from test_framework.test_framework import BitcoinTestFramework
1716
from test_framework.test_node import (
1817
BITCOIN_PID_FILENAME_DEFAULT,
@@ -251,9 +250,8 @@ def break_wait_test(self):
251250
terminal. (This can be different than the node shutdown sequence that
252251
happens when the stop RPC is sent.)
253252
254-
Currently when the break signal is sent, it does not interrupt the
255-
waitforblockheight RPC call, and the node does not exit until it times
256-
out."""
253+
The waitforblockheight call should be interrupted and return right away,
254+
and not time out."""
257255

258256
self.log.info("Testing waitforblockheight RPC call followed by break signal")
259257
node = self.nodes[0]
@@ -287,12 +285,9 @@ def break_wait_test(self):
287285
node.process.send_signal(signal.SIGTERM)
288286
node.process.wait()
289287

290-
try:
291-
result = fut.result()
292-
raise Exception(f"waitforblockheight returned {result!r}")
293-
except JSONRPCException as e:
294-
self.log.debug(f"waitforblockheight raised {e!r}")
295-
assert_equal(e.error['code'], -344) # -344 is RPC timeout
288+
result = fut.result()
289+
self.log.debug(f"waitforblockheight returned {result!r}")
290+
assert_equal(result["height"], current_height)
296291
node.wait_until_stopped()
297292

298293
def run_test(self):

0 commit comments

Comments
 (0)