Bitcoin Core 22.99.0
P2P Digital Currency
shutdown.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2020 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <shutdown.h>
7
8#include <logging.h>
9#include <node/ui_interface.h>
10#include <util/tokenpipe.h>
11#include <warnings.h>
12
14
15#include <assert.h>
16#include <atomic>
17#ifdef WIN32
18#include <condition_variable>
19#endif
20
21bool AbortNode(const std::string& strMessage, bilingual_str user_message)
22{
23 SetMiscWarning(Untranslated(strMessage));
24 LogPrintf("*** %s\n", strMessage);
25 if (user_message.empty()) {
26 user_message = _("A fatal internal error occurred, see debug.log for details");
27 }
28 AbortError(user_message);
30 return false;
31}
32
33static std::atomic<bool> fRequestShutdown(false);
34#ifdef WIN32
36std::mutex g_shutdown_mutex;
37std::condition_variable g_shutdown_cv;
38#else
43#endif
44
46{
47#ifndef WIN32
48 std::optional<TokenPipe> pipe = TokenPipe::Make();
49 if (!pipe) return false;
50 g_shutdown_r = pipe->TakeReadEnd();
51 g_shutdown_w = pipe->TakeWriteEnd();
52#endif
53 return true;
54}
55
57{
58#ifdef WIN32
59 std::unique_lock<std::mutex> lk(g_shutdown_mutex);
60 fRequestShutdown = true;
61 g_shutdown_cv.notify_one();
62#else
63 // This must be reentrant and safe for calling in a signal handler, so using a condition variable is not safe.
64 // Make sure that the token is only written once even if multiple threads call this concurrently or in
65 // case of a reentrant signal.
66 if (!fRequestShutdown.exchange(true)) {
67 // Write an arbitrary byte to the write end of the shutdown pipe.
68 int res = g_shutdown_w.TokenWrite('x');
69 if (res != 0) {
70 LogPrintf("Sending shutdown token failed\n");
71 assert(0);
72 }
73 }
74#endif
75}
76
78{
79 if (fRequestShutdown) {
80 // Cancel existing shutdown by waiting for it, this will reset condition flags and remove
81 // the shutdown token from the pipe.
83 }
84 fRequestShutdown = false;
85}
86
88{
89 return fRequestShutdown;
90}
91
93{
94#ifdef WIN32
95 std::unique_lock<std::mutex> lk(g_shutdown_mutex);
96 g_shutdown_cv.wait(lk, [] { return fRequestShutdown.load(); });
97#else
98 int res = g_shutdown_r.TokenRead();
99 if (res != 'x') {
100 LogPrintf("Reading shutdown token failed\n");
101 assert(0);
102 }
103#endif
104}
One end of a token pipe.
Definition: tokenpipe.h:15
int TokenWrite(uint8_t token)
Write token to endpoint.
Definition: tokenpipe.cpp:38
int TokenRead()
Read token from endpoint.
Definition: tokenpipe.cpp:56
static std::optional< TokenPipe > Make()
Create a new pipe.
Definition: tokenpipe.cpp:82
#define LogPrintf(...)
Definition: logging.h:187
void WaitForShutdown()
Wait for StartShutdown to be called in any thread.
Definition: shutdown.cpp:92
static TokenPipeEnd g_shutdown_w
Definition: shutdown.cpp:42
bool AbortNode(const std::string &strMessage, bilingual_str user_message)
Abort with a message.
Definition: shutdown.cpp:21
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
Definition: shutdown.cpp:87
static std::atomic< bool > fRequestShutdown(false)
static TokenPipeEnd g_shutdown_r
On UNIX-like operating systems use the self-pipe trick.
Definition: shutdown.cpp:41
bool InitShutdownState()
Initialize shutdown state.
Definition: shutdown.cpp:45
void StartShutdown()
Request shutdown of the application.
Definition: shutdown.cpp:56
void AbortShutdown()
Clear shutdown flag.
Definition: shutdown.cpp:77
Bilingual messages:
Definition: translation.h:16
bool empty() const
Definition: translation.h:27
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:63
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:46
constexpr auto AbortError
Definition: ui_interface.h:117
assert(!tx.IsCoinBase())
void SetMiscWarning(const bilingual_str &warning)
Definition: warnings.cpp:19