Bitcoin Core  21.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 
13 #include <config/bitcoin-config.h>
14 
15 #include <assert.h>
16 #include <atomic>
17 #ifdef WIN32
18 #include <condition_variable>
19 #endif
20 
21 bool 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);
29  StartShutdown();
30  return false;
31 }
32 
33 static std::atomic<bool> fRequestShutdown(false);
34 #ifdef WIN32
35 
36 std::mutex g_shutdown_mutex;
37 std::condition_variable g_shutdown_cv;
38 #else
39 
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 }
InitShutdownState
bool InitShutdownState()
Initialize shutdown state.
Definition: shutdown.cpp:45
ShutdownRequested
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
Definition: shutdown.cpp:87
TokenPipeEnd::TokenRead
int TokenRead()
Read token from endpoint.
Definition: tokenpipe.cpp:56
_
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:57
bilingual_str
Bilingual messages:
Definition: translation.h:16
TokenPipeEnd
One end of a token pipe.
Definition: tokenpipe.h:14
TokenPipeEnd::TokenWrite
int TokenWrite(uint8_t token)
Write token to endpoint.
Definition: tokenpipe.cpp:38
fRequestShutdown
static std::atomic< bool > fRequestShutdown(false)
bitcoin-config.h
bilingual_str::empty
bool empty() const
Definition: translation.h:27
shutdown.h
Untranslated
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:40
g_shutdown_r
static TokenPipeEnd g_shutdown_r
On UNIX-like operating systems use the self-pipe trick.
Definition: shutdown.cpp:41
tokenpipe.h
SetMiscWarning
void SetMiscWarning(const bilingual_str &warning)
Definition: warnings.cpp:19
LogPrintf
#define LogPrintf(...)
Definition: logging.h:183
WaitForShutdown
void WaitForShutdown()
Wait for StartShutdown to be called in any thread.
Definition: shutdown.cpp:92
ui_interface.h
TokenPipe::Make
static std::optional< TokenPipe > Make()
Create a new pipe.
Definition: tokenpipe.cpp:82
logging.h
AbortNode
bool AbortNode(const std::string &strMessage, bilingual_str user_message)
Abort with a message.
Definition: shutdown.cpp:21
AbortError
constexpr auto AbortError
Definition: ui_interface.h:117
g_shutdown_w
static TokenPipeEnd g_shutdown_w
Definition: shutdown.cpp:42
assert
assert(std::addressof(::ChainstateActive().CoinsTip())==std::addressof(coins_cache))
warnings.h
StartShutdown
void StartShutdown()
Request shutdown of the application.
Definition: shutdown.cpp:56
AbortShutdown
void AbortShutdown()
Clear shutdown flag.
Definition: shutdown.cpp:77