mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 15:09:59 +01:00
util: Get rid of uncaught exceptions thrown by SignalInterrupt class
Replace exceptions thrown by signal and wait methods with [[nodiscard]] return values. This is mostly a refactoring, but there is a slight change of behavior if AbortShutdown function fails. The original behavior which was unintentionally changed in #27861 is restored, so it now triggers an assert failure again instead of throwing an exception. (The AbortShutdown function is only ever called in the the GUI version of Bitcoin Core when corruption is detected on loading and the user tries to reindex.) Problems with using exceptions were pointed out by MarcoFalke in https://github.com/bitcoin/bitcoin/pull/27861#discussion_r1255496707.
This commit is contained in:
@@ -15,9 +15,7 @@
|
|||||||
|
|
||||||
void StartShutdown()
|
void StartShutdown()
|
||||||
{
|
{
|
||||||
try {
|
if (!Assert(kernel::g_context)->interrupt()) {
|
||||||
Assert(kernel::g_context)->interrupt();
|
|
||||||
} catch (const std::system_error&) {
|
|
||||||
LogPrintf("Sending shutdown token failed\n");
|
LogPrintf("Sending shutdown token failed\n");
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
@@ -25,7 +23,10 @@ void StartShutdown()
|
|||||||
|
|
||||||
void AbortShutdown()
|
void AbortShutdown()
|
||||||
{
|
{
|
||||||
Assert(kernel::g_context)->interrupt.reset();
|
if (!Assert(kernel::g_context)->interrupt.reset()) {
|
||||||
|
LogPrintf("Reading shutdown token failed\n");
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShutdownRequested()
|
bool ShutdownRequested()
|
||||||
@@ -35,9 +36,7 @@ bool ShutdownRequested()
|
|||||||
|
|
||||||
void WaitForShutdown()
|
void WaitForShutdown()
|
||||||
{
|
{
|
||||||
try {
|
if (!Assert(kernel::g_context)->interrupt.wait()) {
|
||||||
Assert(kernel::g_context)->interrupt.wait();
|
|
||||||
} catch (const std::system_error&) {
|
|
||||||
LogPrintf("Reading shutdown token failed\n");
|
LogPrintf("Reading shutdown token failed\n");
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,15 +30,16 @@ SignalInterrupt::operator bool() const
|
|||||||
return m_flag;
|
return m_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignalInterrupt::reset()
|
bool SignalInterrupt::reset()
|
||||||
{
|
{
|
||||||
// Cancel existing interrupt by waiting for it, this will reset condition flags and remove
|
// Cancel existing interrupt by waiting for it, this will reset condition flags and remove
|
||||||
// the token from the pipe.
|
// the token from the pipe.
|
||||||
if (*this) wait();
|
if (*this && !wait()) return false;
|
||||||
m_flag = false;
|
m_flag = false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignalInterrupt::operator()()
|
bool SignalInterrupt::operator()()
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
std::unique_lock<std::mutex> lk(m_mutex);
|
std::unique_lock<std::mutex> lk(m_mutex);
|
||||||
@@ -52,13 +53,14 @@ void SignalInterrupt::operator()()
|
|||||||
// Write an arbitrary byte to the write end of the pipe.
|
// Write an arbitrary byte to the write end of the pipe.
|
||||||
int res = m_pipe_w.TokenWrite('x');
|
int res = m_pipe_w.TokenWrite('x');
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
throw std::ios_base::failure("Could not write interrupt token");
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignalInterrupt::wait()
|
bool SignalInterrupt::wait()
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
std::unique_lock<std::mutex> lk(m_mutex);
|
std::unique_lock<std::mutex> lk(m_mutex);
|
||||||
@@ -66,9 +68,10 @@ void SignalInterrupt::wait()
|
|||||||
#else
|
#else
|
||||||
int res = m_pipe_r.TokenRead();
|
int res = m_pipe_r.TokenRead();
|
||||||
if (res != 'x') {
|
if (res != 'x') {
|
||||||
throw std::ios_base::failure("Did not read expected interrupt token");
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ class SignalInterrupt
|
|||||||
public:
|
public:
|
||||||
SignalInterrupt();
|
SignalInterrupt();
|
||||||
explicit operator bool() const;
|
explicit operator bool() const;
|
||||||
void operator()();
|
[[nodiscard]] bool operator()();
|
||||||
void reset();
|
[[nodiscard]] bool reset();
|
||||||
void wait();
|
[[nodiscard]] bool wait();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic<bool> m_flag;
|
std::atomic<bool> m_flag;
|
||||||
|
|||||||
Reference in New Issue
Block a user