Support for multiple InsightWorker threads. We now have three InsightWorker threads as opposed to one

This commit is contained in:
Nav
2022-09-08 16:07:22 +01:00
parent 77cd13bf46
commit 1ddff3c2a4
4 changed files with 42 additions and 29 deletions

View File

@@ -42,7 +42,7 @@ Bloom and thus the connected AVR target. The DebugServer runs on a dedicated thr
##### Insight
Insight is a graphical user interface that provides insight into the connected target. It presents the target's
memories, GPIO pin states & registers, along with the ability to manipulate them. Insight occupies Bloom's main thread
and employs a single worker thread for background tasks. Unlike other components within Bloom, Insight relies heavily
and employs several worker threads for background tasks. Unlike other components within Bloom, Insight relies heavily
on the Qt framework for its GUI capabilities and other useful utilities. See source code in src/Insight/ for more.
##### SignalHandler

View File

@@ -45,7 +45,6 @@ namespace Bloom
try {
this->startup();
this->workerThread->start();
this->setThreadState(ThreadState::READY);
Logger::info("Insight ready");
this->application.exec();
@@ -179,20 +178,31 @@ namespace Bloom
this->mainWindow->setInsightConfig(this->insightConfig);
this->mainWindow->setEnvironmentConfig(this->environmentConfig);
// Prepare worker thread
this->workerThread = new QThread();
this->workerThread->setObjectName("IW" + QString::number(this->insightWorker->id));
this->insightWorker->moveToThread(this->workerThread);
QObject::connect(this->workerThread, &QThread::started, this->insightWorker, &InsightWorker::startup);
QObject::connect(this->workerThread, &QThread::finished, this->insightWorker, &QObject::deleteLater);
QObject::connect(this->workerThread, &QThread::finished, this->workerThread, &QThread::deleteLater);
// Construct and start worker threads
for (std::uint8_t i = 0; i < Insight::INSIGHT_WORKER_COUNT; ++i) {
auto* insightWorker = new InsightWorker();
auto* workerThread = new QThread();
this->mainWindow->init(this->targetControllerConsole.getTargetDescriptor());
workerThread->setObjectName("IW" + QString::number(insightWorker->id));
insightWorker->moveToThread(workerThread);
QObject::connect(workerThread, &QThread::started, insightWorker, &InsightWorker::startup);
QObject::connect(workerThread, &QThread::finished, insightWorker, &QObject::deleteLater);
QObject::connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater);
QObject::connect(this->insightWorker, &InsightWorker::ready, this, [this] {
this->insightWorkersById[insightWorker->id] = std::pair(insightWorker, workerThread);
// TODO: Remove this hack. Find a better way to trigger the latest version check.
if (i == 0) {
QObject::connect(insightWorker, &InsightWorker::ready, this, [this] {
this->checkBloomVersion();
});
}
Logger::debug("Starting InsightWorker" + std::to_string(insightWorker->id) + " thread");
workerThread->start();
}
this->mainWindow->init(this->targetControllerConsole.getTargetDescriptor());
this->mainWindow->show();
}
@@ -205,11 +215,15 @@ namespace Bloom
this->mainWindow->close();
if (this->workerThread != nullptr && this->workerThread->isRunning()) {
Logger::debug("Stopping InsightWorker thread");
this->workerThread->quit();
Logger::debug("Waiting for InsightWorker thread to stop");
this->workerThread->wait();
for (auto& [workerId, workerPair] : this->insightWorkersById) {
auto* workerThread = workerPair.second;
if (workerThread != nullptr && workerThread->isRunning()) {
Logger::debug("Stopping InsightWorker" + std::to_string(workerId) + " thread");
workerThread->quit();
Logger::debug("Waiting for InsightWorker" + std::to_string(workerId) + " thread to stop");
workerThread->wait();
}
}
this->application.exit(0);
@@ -237,7 +251,7 @@ namespace Bloom
}
);
this->insightWorker->queueTask(versionQueryTask);
InsightWorker::queueTask(versionQueryTask);
}
void Insight::onInsightWindowActivated() {

View File

@@ -2,6 +2,10 @@
#include <QtCore>
#include <QApplication>
#include <cstdint>
#include <map>
#include <utility>
#include <QThread>
#include "src/Helpers/Thread.hpp"
#include "src/Helpers/Paths.hpp"
@@ -62,6 +66,7 @@ namespace Bloom
void shutdown();
private:
static constexpr std::uint8_t INSIGHT_WORKER_COUNT = 3;
std::string qtApplicationName = "Bloom";
std::array<char*, 1> qtApplicationArgv = {this->qtApplicationName.data()};
int qtApplicationArgc = 1;
@@ -75,7 +80,9 @@ namespace Bloom
EventListener& eventListener;
QApplication application;
InsightWorker* insightWorker = new InsightWorker();
std::map<decltype(InsightWorker::id), std::pair<InsightWorker*, QThread*>> insightWorkersById;
InsightWindow* mainWindow = new InsightWindow(
this->environmentConfig,
this->insightConfig,
@@ -86,12 +93,6 @@ namespace Bloom
Targets::TargetState lastTargetState = Targets::TargetState::UNKNOWN;
InsightSignals* insightSignals = InsightSignals::instance();
/**
* Insight consists of two threads - the main thread where the main Qt event loop runs (for the GUI), and
* a single worker thread to handle any blocking/time-expensive operations.
*/
QThread* workerThread = nullptr;
void startup();
/**

View File

@@ -12,8 +12,6 @@ namespace Bloom
using Bloom::Targets::TargetState;
void InsightWorker::startup() {
Logger::debug("Starting InsightWorker" + std::to_string(this->id) + " thread");
QObject::connect(
InsightSignals::instance(),
&InsightSignals::taskQueued,