diff options
author | W. J. van der Laan <laanwj@protonmail.com> | 2021-07-22 09:47:13 +0200 |
---|---|---|
committer | W. J. van der Laan <laanwj@protonmail.com> | 2021-07-22 10:02:10 +0200 |
commit | 36aee0f3538ec3399a3838041ea5993aba5f518b (patch) | |
tree | 9c73d5ce58b8ff5ac6e61b1efcd1c0b5e8328cda /src/qt | |
parent | ba15ab4990459d16da94786668b88e4d74b23033 (diff) | |
parent | 8169fc4e73a87331e02502fc24e293831765c8b1 (diff) |
Merge bitcoin-core/gui#381: refactor: Make BitcoinCore class reusable
8169fc4e73a87331e02502fc24e293831765c8b1 qt, refactor: Fix code styling of moved InitExecutor class (Hennadii Stepanov)
c82165a55701fe4ff604d7f30163051cd47c2363 qt, refactor: Move InitExecutor class into its own module (Hennadii Stepanov)
dbcf56b6c6e939923673b3f07bed7bb3632dbeb1 scripted-diff: Rename BitcoinCore class to InitExecutor (Hennadii Stepanov)
19a1d008310f250b69b7aa764a9f26384d5a4a85 qt: Add BitcoinCore::m_thread member (Hennadii Stepanov)
Pull request description:
This PR makes the `BitcoinCore` class reusable, i.e., it can be used by the widget-based GUI or by the [QML-based](https://github.com/bitcoin-core/gui-qml/tree/main/src/qml) one, and it makes the divergence between these two repos minimal.
The small benefit to the current branch is more structured code.
Actually, this PR is ported from https://github.com/bitcoin-core/gui-qml/pull/10.
The example of the re-using of the `BitcoinCore` class is https://github.com/bitcoin-core/gui-qml/pull/11.
ACKs for top commit:
laanwj:
ACK 8169fc4e73a87331e02502fc24e293831765c8b1
ryanofsky:
Code review ACK 8169fc4e73a87331e02502fc24e293831765c8b1. Only change is switching from `m_executor` from pointer to optional type (thanks for update!)
Tree-SHA512: a0552c32d26d9acf42921eb12bcdf68f02d52f7183c688c43257b1a58679f64e45f193ee2d316850c7f0f516561e17abe989fe545bfa05e158ad3f4c66d19bca
Diffstat (limited to 'src/qt')
-rw-r--r-- | src/qt/bitcoin.cpp | 99 | ||||
-rw-r--r-- | src/qt/bitcoin.h | 34 | ||||
-rw-r--r-- | src/qt/initexecutor.cpp | 66 | ||||
-rw-r--r-- | src/qt/initexecutor.h | 46 | ||||
-rw-r--r-- | src/qt/test/test_main.cpp | 1 |
5 files changed, 140 insertions, 106 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 442c813a5a..4ab4e388d9 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -7,12 +7,19 @@ #endif #include <qt/bitcoin.h> -#include <qt/bitcoingui.h> #include <chainparams.h> +#include <init.h> +#include <interfaces/handler.h> +#include <interfaces/node.h> +#include <node/context.h> +#include <node/ui_interface.h> +#include <noui.h> +#include <qt/bitcoingui.h> #include <qt/clientmodel.h> #include <qt/guiconstants.h> #include <qt/guiutil.h> +#include <qt/initexecutor.h> #include <qt/intro.h> #include <qt/networkstyle.h> #include <qt/optionsmodel.h> @@ -20,6 +27,11 @@ #include <qt/splashscreen.h> #include <qt/utilitydialog.h> #include <qt/winshutdownmonitor.h> +#include <uint256.h> +#include <util/system.h> +#include <util/threadnames.h> +#include <util/translation.h> +#include <validation.h> #ifdef ENABLE_WALLET #include <qt/paymentserver.h> @@ -27,18 +39,6 @@ #include <qt/walletmodel.h> #endif // ENABLE_WALLET -#include <init.h> -#include <interfaces/handler.h> -#include <interfaces/node.h> -#include <node/context.h> -#include <node/ui_interface.h> -#include <noui.h> -#include <uint256.h> -#include <util/system.h> -#include <util/threadnames.h> -#include <util/translation.h> -#include <validation.h> - #include <boost/signals2/connection.hpp> #include <memory> @@ -155,54 +155,11 @@ void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, cons } } -BitcoinCore::BitcoinCore(interfaces::Node& node) : - QObject(), m_node(node) -{ -} - -void BitcoinCore::handleRunawayException(const std::exception *e) -{ - PrintExceptionContinue(e, "Runaway exception"); - Q_EMIT runawayException(QString::fromStdString(m_node.getWarnings().translated)); -} - -void BitcoinCore::initialize() -{ - try - { - util::ThreadRename("qt-init"); - qDebug() << __func__ << ": Running initialization in thread"; - interfaces::BlockAndHeaderTipInfo tip_info; - bool rv = m_node.appInitMain(&tip_info); - Q_EMIT initializeResult(rv, tip_info); - } catch (const std::exception& e) { - handleRunawayException(&e); - } catch (...) { - handleRunawayException(nullptr); - } -} - -void BitcoinCore::shutdown() -{ - try - { - qDebug() << __func__ << ": Running Shutdown in thread"; - m_node.appShutdown(); - qDebug() << __func__ << ": Shutdown finished"; - Q_EMIT shutdownResult(); - } catch (const std::exception& e) { - handleRunawayException(&e); - } catch (...) { - handleRunawayException(nullptr); - } -} - static int qt_argc = 1; static const char* qt_argv = "bitcoin-qt"; BitcoinApplication::BitcoinApplication(): QApplication(qt_argc, const_cast<char **>(&qt_argv)), - coreThread(nullptr), optionsModel(nullptr), clientModel(nullptr), window(nullptr), @@ -230,13 +187,7 @@ void BitcoinApplication::setupPlatformStyle() BitcoinApplication::~BitcoinApplication() { - if(coreThread) - { - qDebug() << __func__ << ": Stopping thread"; - coreThread->quit(); - coreThread->wait(); - qDebug() << __func__ << ": Stopped thread"; - } + m_executor.reset(); delete window; window = nullptr; @@ -291,22 +242,15 @@ bool BitcoinApplication::baseInitialize() void BitcoinApplication::startThread() { - if(coreThread) - return; - coreThread = new QThread(this); - BitcoinCore *executor = new BitcoinCore(node()); - executor->moveToThread(coreThread); + assert(!m_executor); + m_executor.emplace(node()); /* communication to and from thread */ - connect(executor, &BitcoinCore::initializeResult, this, &BitcoinApplication::initializeResult); - connect(executor, &BitcoinCore::shutdownResult, this, &BitcoinApplication::shutdownResult); - connect(executor, &BitcoinCore::runawayException, this, &BitcoinApplication::handleRunawayException); - connect(this, &BitcoinApplication::requestedInitialize, executor, &BitcoinCore::initialize); - connect(this, &BitcoinApplication::requestedShutdown, executor, &BitcoinCore::shutdown); - /* make sure executor object is deleted in its own thread */ - connect(coreThread, &QThread::finished, executor, &QObject::deleteLater); - - coreThread->start(); + connect(&m_executor.value(), &InitExecutor::initializeResult, this, &BitcoinApplication::initializeResult); + connect(&m_executor.value(), &InitExecutor::shutdownResult, this, &BitcoinApplication::shutdownResult); + connect(&m_executor.value(), &InitExecutor::runawayException, this, &BitcoinApplication::handleRunawayException); + connect(this, &BitcoinApplication::requestedInitialize, &m_executor.value(), &InitExecutor::initialize); + connect(this, &BitcoinApplication::requestedShutdown, &m_executor.value(), &InitExecutor::shutdown); } void BitcoinApplication::parameterSetup() @@ -339,7 +283,6 @@ void BitcoinApplication::requestShutdown() shutdownWindow.reset(ShutdownWindow::showShutdownWindow(window)); qDebug() << __func__ << ": Requesting shutdown"; - startThread(); window->hide(); // Must disconnect node signals otherwise current thread can deadlock since // no event loop is running. diff --git a/src/qt/bitcoin.h b/src/qt/bitcoin.h index f9fab0534b..ed2f26b7f3 100644 --- a/src/qt/bitcoin.h +++ b/src/qt/bitcoin.h @@ -9,11 +9,14 @@ #include <config/bitcoin-config.h> #endif -#include <QApplication> +#include <interfaces/node.h> +#include <qt/initexecutor.h> + #include <assert.h> #include <memory> +#include <optional> -#include <interfaces/node.h> +#include <QApplication> class BitcoinGUI; class ClientModel; @@ -26,31 +29,6 @@ class WalletController; class WalletModel; -/** Class encapsulating Bitcoin Core startup and shutdown. - * Allows running startup and shutdown in a different thread from the UI thread. - */ -class BitcoinCore: public QObject -{ - Q_OBJECT -public: - explicit BitcoinCore(interfaces::Node& node); - -public Q_SLOTS: - void initialize(); - void shutdown(); - -Q_SIGNALS: - void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info); - void shutdownResult(); - void runawayException(const QString &message); - -private: - /// Pass fatal exception message to UI thread - void handleRunawayException(const std::exception *e); - - interfaces::Node& m_node; -}; - /** Main Bitcoin application object */ class BitcoinApplication: public QApplication { @@ -112,7 +90,7 @@ Q_SIGNALS: void windowShown(BitcoinGUI* window); private: - QThread *coreThread; + std::optional<InitExecutor> m_executor; OptionsModel *optionsModel; ClientModel *clientModel; BitcoinGUI *window; diff --git a/src/qt/initexecutor.cpp b/src/qt/initexecutor.cpp new file mode 100644 index 0000000000..7060f74dab --- /dev/null +++ b/src/qt/initexecutor.cpp @@ -0,0 +1,66 @@ +// Copyright (c) 2014-2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <qt/initexecutor.h> + +#include <interfaces/node.h> +#include <util/system.h> +#include <util/threadnames.h> + +#include <exception> + +#include <QDebug> +#include <QObject> +#include <QString> +#include <QThread> + +InitExecutor::InitExecutor(interfaces::Node& node) + : QObject(), m_node(node) +{ + this->moveToThread(&m_thread); + m_thread.start(); +} + +InitExecutor::~InitExecutor() +{ + qDebug() << __func__ << ": Stopping thread"; + m_thread.quit(); + m_thread.wait(); + qDebug() << __func__ << ": Stopped thread"; +} + +void InitExecutor::handleRunawayException(const std::exception* e) +{ + PrintExceptionContinue(e, "Runaway exception"); + Q_EMIT runawayException(QString::fromStdString(m_node.getWarnings().translated)); +} + +void InitExecutor::initialize() +{ + try { + util::ThreadRename("qt-init"); + qDebug() << __func__ << ": Running initialization in thread"; + interfaces::BlockAndHeaderTipInfo tip_info; + bool rv = m_node.appInitMain(&tip_info); + Q_EMIT initializeResult(rv, tip_info); + } catch (const std::exception& e) { + handleRunawayException(&e); + } catch (...) { + handleRunawayException(nullptr); + } +} + +void InitExecutor::shutdown() +{ + try { + qDebug() << __func__ << ": Running Shutdown in thread"; + m_node.appShutdown(); + qDebug() << __func__ << ": Shutdown finished"; + Q_EMIT shutdownResult(); + } catch (const std::exception& e) { + handleRunawayException(&e); + } catch (...) { + handleRunawayException(nullptr); + } +} diff --git a/src/qt/initexecutor.h b/src/qt/initexecutor.h new file mode 100644 index 0000000000..319ce40465 --- /dev/null +++ b/src/qt/initexecutor.h @@ -0,0 +1,46 @@ +// Copyright (c) 2014-2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_INITEXECUTOR_H +#define BITCOIN_QT_INITEXECUTOR_H + +#include <interfaces/node.h> + +#include <exception> + +#include <QObject> +#include <QThread> + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +/** Class encapsulating Bitcoin Core startup and shutdown. + * Allows running startup and shutdown in a different thread from the UI thread. + */ +class InitExecutor : public QObject +{ + Q_OBJECT +public: + explicit InitExecutor(interfaces::Node& node); + ~InitExecutor(); + +public Q_SLOTS: + void initialize(); + void shutdown(); + +Q_SIGNALS: + void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info); + void shutdownResult(); + void runawayException(const QString& message); + +private: + /// Pass fatal exception message to UI thread + void handleRunawayException(const std::exception* e); + + interfaces::Node& m_node; + QThread m_thread; +}; + +#endif // BITCOIN_QT_INITEXECUTOR_H diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index eb86f027ef..7d66f67f8a 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -8,6 +8,7 @@ #include <interfaces/node.h> #include <qt/bitcoin.h> +#include <qt/initexecutor.h> #include <qt/test/apptests.h> #include <qt/test/rpcnestedtests.h> #include <qt/test/uritests.h> |