From 8278e8ab0fd971451360874f746ad04c248e6172 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Mon, 14 Oct 2019 20:46:34 +0100 Subject: [PATCH] merge bitcoin#17135: Make polling in ClientModel asynchronous --- src/qt/clientmodel.cpp | 31 +++++++++++++++++++------------ src/qt/clientmodel.h | 4 ++-- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 11e459fd8e..bf400d8ae6 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -29,6 +29,7 @@ #include #include +#include #include static int64_t nLastHeaderTipUpdateNotification = 0; @@ -40,23 +41,37 @@ ClientModel::ClientModel(interfaces::Node& node, OptionsModel *_optionsModel, QO optionsModel(_optionsModel), peerTableModel(nullptr), banTableModel(nullptr), - pollTimer(nullptr) + m_thread(new QThread(this)) { cachedBestHeaderHeight = -1; cachedBestHeaderTime = -1; peerTableModel = new PeerTableModel(m_node, this); banTableModel = new BanTableModel(m_node, this); - pollTimer = new QTimer(this); - connect(pollTimer, &QTimer::timeout, this, &ClientModel::updateTimer); - pollTimer->start(MODEL_UPDATE_DELAY); mnListCached = std::make_shared(); + QTimer* timer = new QTimer; + timer->setInterval(MODEL_UPDATE_DELAY); + connect(timer, &QTimer::timeout, [this] { + // no locking required at this point + // the following calls will acquire the required lock + Q_EMIT mempoolSizeChanged(m_node.getMempoolSize(), m_node.getMempoolDynamicUsage()); + Q_EMIT islockCountChanged(m_node.llmq().getInstantSentLockCount()); + }); + connect(m_thread, &QThread::finished, timer, &QObject::deleteLater); + connect(m_thread, &QThread::started, [timer] { timer->start(); }); + // move timer to thread so that polling doesn't disturb main event loop + timer->moveToThread(m_thread); + m_thread->start(); + subscribeToCoreSignals(); } ClientModel::~ClientModel() { unsubscribeFromCoreSignals(); + + m_thread->quit(); + m_thread->wait(); } int ClientModel::getNumConnections(unsigned int flags) const @@ -128,14 +143,6 @@ std::vector ClientModel::getAllGovernanceObjects() return m_node.gov().getAllNewerThan(0); } -void ClientModel::updateTimer() -{ - // no locking required at this point - // the following calls will acquire the required lock - Q_EMIT mempoolSizeChanged(m_node.getMempoolSize(), m_node.getMempoolDynamicUsage()); - Q_EMIT islockCountChanged(m_node.llmq().getInstantSentLockCount()); -} - void ClientModel::updateNumConnections(int numConnections) { Q_EMIT numConnectionsChanged(numConnections); diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 69d16b7bba..77224c4c3a 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -104,7 +104,8 @@ private: PeerTableModel *peerTableModel; BanTableModel *banTableModel; - QTimer *pollTimer; + //! A thread to interact with m_node asynchronously + QThread* const m_thread; // The cache for mn list is not technically needed because CDeterministicMNManager // caches it internally for recent blocks but it's not enough to get consistent @@ -133,7 +134,6 @@ Q_SIGNALS: void showProgress(const QString &title, int nProgress); public Q_SLOTS: - void updateTimer(); void updateNumConnections(int numConnections); void updateNetworkActive(bool networkActive); void updateAlert();