Support for multiple InsightWorker threads. We now have three InsightWorker threads as opposed to one
This commit is contained in:
@@ -42,7 +42,7 @@ Bloom and thus the connected AVR target. The DebugServer runs on a dedicated thr
|
|||||||
##### Insight
|
##### Insight
|
||||||
Insight is a graphical user interface that provides insight into the connected target. It presents the target's
|
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
|
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.
|
on the Qt framework for its GUI capabilities and other useful utilities. See source code in src/Insight/ for more.
|
||||||
|
|
||||||
##### SignalHandler
|
##### SignalHandler
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ namespace Bloom
|
|||||||
try {
|
try {
|
||||||
this->startup();
|
this->startup();
|
||||||
|
|
||||||
this->workerThread->start();
|
|
||||||
this->setThreadState(ThreadState::READY);
|
this->setThreadState(ThreadState::READY);
|
||||||
Logger::info("Insight ready");
|
Logger::info("Insight ready");
|
||||||
this->application.exec();
|
this->application.exec();
|
||||||
@@ -179,20 +178,31 @@ namespace Bloom
|
|||||||
this->mainWindow->setInsightConfig(this->insightConfig);
|
this->mainWindow->setInsightConfig(this->insightConfig);
|
||||||
this->mainWindow->setEnvironmentConfig(this->environmentConfig);
|
this->mainWindow->setEnvironmentConfig(this->environmentConfig);
|
||||||
|
|
||||||
// Prepare worker thread
|
// Construct and start worker threads
|
||||||
this->workerThread = new QThread();
|
for (std::uint8_t i = 0; i < Insight::INSIGHT_WORKER_COUNT; ++i) {
|
||||||
this->workerThread->setObjectName("IW" + QString::number(this->insightWorker->id));
|
auto* insightWorker = new InsightWorker();
|
||||||
this->insightWorker->moveToThread(this->workerThread);
|
auto* workerThread = new QThread();
|
||||||
QObject::connect(this->workerThread, &QThread::started, this->insightWorker, &InsightWorker::startup);
|
|
||||||
QObject::connect(this->workerThread, &QThread::finished, this->insightWorker, &QObject::deleteLater);
|
workerThread->setObjectName("IW" + QString::number(insightWorker->id));
|
||||||
QObject::connect(this->workerThread, &QThread::finished, this->workerThread, &QThread::deleteLater);
|
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);
|
||||||
|
|
||||||
|
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->init(this->targetControllerConsole.getTargetDescriptor());
|
||||||
|
|
||||||
QObject::connect(this->insightWorker, &InsightWorker::ready, this, [this] {
|
|
||||||
this->checkBloomVersion();
|
|
||||||
});
|
|
||||||
|
|
||||||
this->mainWindow->show();
|
this->mainWindow->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,11 +215,15 @@ namespace Bloom
|
|||||||
|
|
||||||
this->mainWindow->close();
|
this->mainWindow->close();
|
||||||
|
|
||||||
if (this->workerThread != nullptr && this->workerThread->isRunning()) {
|
for (auto& [workerId, workerPair] : this->insightWorkersById) {
|
||||||
Logger::debug("Stopping InsightWorker thread");
|
auto* workerThread = workerPair.second;
|
||||||
this->workerThread->quit();
|
|
||||||
Logger::debug("Waiting for InsightWorker thread to stop");
|
if (workerThread != nullptr && workerThread->isRunning()) {
|
||||||
this->workerThread->wait();
|
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);
|
this->application.exit(0);
|
||||||
@@ -237,7 +251,7 @@ namespace Bloom
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
this->insightWorker->queueTask(versionQueryTask);
|
InsightWorker::queueTask(versionQueryTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Insight::onInsightWindowActivated() {
|
void Insight::onInsightWindowActivated() {
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
#include "src/Helpers/Thread.hpp"
|
#include "src/Helpers/Thread.hpp"
|
||||||
#include "src/Helpers/Paths.hpp"
|
#include "src/Helpers/Paths.hpp"
|
||||||
@@ -62,6 +66,7 @@ namespace Bloom
|
|||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr std::uint8_t INSIGHT_WORKER_COUNT = 3;
|
||||||
std::string qtApplicationName = "Bloom";
|
std::string qtApplicationName = "Bloom";
|
||||||
std::array<char*, 1> qtApplicationArgv = {this->qtApplicationName.data()};
|
std::array<char*, 1> qtApplicationArgv = {this->qtApplicationName.data()};
|
||||||
int qtApplicationArgc = 1;
|
int qtApplicationArgc = 1;
|
||||||
@@ -75,7 +80,9 @@ namespace Bloom
|
|||||||
EventListener& eventListener;
|
EventListener& eventListener;
|
||||||
|
|
||||||
QApplication application;
|
QApplication application;
|
||||||
InsightWorker* insightWorker = new InsightWorker();
|
|
||||||
|
std::map<decltype(InsightWorker::id), std::pair<InsightWorker*, QThread*>> insightWorkersById;
|
||||||
|
|
||||||
InsightWindow* mainWindow = new InsightWindow(
|
InsightWindow* mainWindow = new InsightWindow(
|
||||||
this->environmentConfig,
|
this->environmentConfig,
|
||||||
this->insightConfig,
|
this->insightConfig,
|
||||||
@@ -86,12 +93,6 @@ namespace Bloom
|
|||||||
Targets::TargetState lastTargetState = Targets::TargetState::UNKNOWN;
|
Targets::TargetState lastTargetState = Targets::TargetState::UNKNOWN;
|
||||||
InsightSignals* insightSignals = InsightSignals::instance();
|
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();
|
void startup();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ namespace Bloom
|
|||||||
using Bloom::Targets::TargetState;
|
using Bloom::Targets::TargetState;
|
||||||
|
|
||||||
void InsightWorker::startup() {
|
void InsightWorker::startup() {
|
||||||
Logger::debug("Starting InsightWorker" + std::to_string(this->id) + " thread");
|
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
InsightSignals::instance(),
|
InsightSignals::instance(),
|
||||||
&InsightSignals::taskQueued,
|
&InsightSignals::taskQueued,
|
||||||
|
|||||||
Reference in New Issue
Block a user