diff options
author | Wladimir J. van der Laan <laanwj@protonmail.com> | 2019-10-26 11:49:34 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@protonmail.com> | 2019-10-26 11:49:51 +0200 |
commit | e9f73b839ad9732d7c8f2f4fcbf6ef8eaa267fa3 (patch) | |
tree | ef16b777c3c4f5f6622c05103252345a424c57ca | |
parent | d91af4768c1cbc1a6ec0f69a3a6d17f69c0cee07 (diff) | |
parent | 6b6be41c36e4fe9a74bed50e7f0a06532ab1260b (diff) |
Merge #17135: gui: Make polling in ClientModel asynchronous
6b6be41c36e4fe9a74bed50e7f0a06532ab1260b gui: Make polling in ClientModel asynchronous (João Barbosa)
Pull request description:
After #14193 `ClientModel::updateTimer` can take some time, as such the GUI hangs, like #17112.
Fixes this by polling in a background thread and updating the GUI asynchronously.
ACKs for top commit:
laanwj:
ACK 6b6be41c36e4fe9a74bed50e7f0a06532ab1260b
Sjors:
Code review re-ACK 6b6be41; only replaced the scary cast with `{ timer->start(); }`
Tree-SHA512: fd98b0c6535441aee3ee03c48b58b4b1f9bdd172ec6b8150da883022f719df34cabfd4c133412bf410e7f709f7bf1e9ef16dca05ef1f3689d526ceaeee51de38
-rw-r--r-- | src/qt/clientmodel.cpp | 31 | ||||
-rw-r--r-- | 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 238be08480..5b216b2705 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -19,6 +19,7 @@ #include <stdint.h> #include <QDebug> +#include <QThread> #include <QTimer> static int64_t nLastHeaderTipUpdateNotification = 0; @@ -30,15 +31,26 @@ 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); + + 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 bytesChanged(m_node.getTotalBytesRecv(), m_node.getTotalBytesSent()); + }); + 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(); } @@ -46,6 +58,9 @@ ClientModel::ClientModel(interfaces::Node& node, OptionsModel *_optionsModel, QO ClientModel::~ClientModel() { unsubscribeFromCoreSignals(); + + m_thread->quit(); + m_thread->wait(); } int ClientModel::getNumConnections(unsigned int flags) const @@ -90,14 +105,6 @@ int64_t ClientModel::getHeaderTipTime() const return cachedBestHeaderTime; } -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 bytesChanged(m_node.getTotalBytesRecv(), m_node.getTotalBytesSent()); -} - void ClientModel::updateNumConnections(int numConnections) { Q_EMIT numConnectionsChanged(numConnections); diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 95f4521f06..d3a95d531e 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -90,7 +90,8 @@ private: PeerTableModel *peerTableModel; BanTableModel *banTableModel; - QTimer *pollTimer; + //! A thread to interact with m_node asynchronously + QThread* const m_thread; void subscribeToCoreSignals(); void unsubscribeFromCoreSignals(); @@ -110,7 +111,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(); |