aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@protonmail.com>2019-10-26 11:49:34 +0200
committerWladimir J. van der Laan <laanwj@protonmail.com>2019-10-26 11:49:51 +0200
commite9f73b839ad9732d7c8f2f4fcbf6ef8eaa267fa3 (patch)
treeef16b777c3c4f5f6622c05103252345a424c57ca
parentd91af4768c1cbc1a6ec0f69a3a6d17f69c0cee07 (diff)
parent6b6be41c36e4fe9a74bed50e7f0a06532ab1260b (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.cpp31
-rw-r--r--src/qt/clientmodel.h4
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();