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