From 8f7076cd0972608c0010bc73e41ab846d9b5b2c3 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 18 May 2024 11:08:48 -0500 Subject: [PATCH] Add thread manager for QThreads --- scwx-qt/scwx-qt.cmake | 2 + scwx-qt/source/scwx/qt/main/main.cpp | 4 + .../source/scwx/qt/manager/thread_manager.cpp | 83 +++++++++++++++++++ .../source/scwx/qt/manager/thread_manager.hpp | 37 +++++++++ 4 files changed, 126 insertions(+) create mode 100644 scwx-qt/source/scwx/qt/manager/thread_manager.cpp create mode 100644 scwx-qt/source/scwx/qt/manager/thread_manager.hpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 47340552..cb48e893 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -99,6 +99,7 @@ set(HDR_MANAGER source/scwx/qt/manager/alert_manager.hpp source/scwx/qt/manager/resource_manager.hpp source/scwx/qt/manager/settings_manager.hpp source/scwx/qt/manager/text_event_manager.hpp + source/scwx/qt/manager/thread_manager.hpp source/scwx/qt/manager/timeline_manager.hpp source/scwx/qt/manager/update_manager.hpp) set(SRC_MANAGER source/scwx/qt/manager/alert_manager.cpp @@ -113,6 +114,7 @@ set(SRC_MANAGER source/scwx/qt/manager/alert_manager.cpp source/scwx/qt/manager/resource_manager.cpp source/scwx/qt/manager/settings_manager.cpp source/scwx/qt/manager/text_event_manager.cpp + source/scwx/qt/manager/thread_manager.cpp source/scwx/qt/manager/timeline_manager.cpp source/scwx/qt/manager/update_manager.cpp) set(HDR_MAP source/scwx/qt/map/alert_layer.hpp diff --git a/scwx-qt/source/scwx/qt/main/main.cpp b/scwx-qt/source/scwx/qt/main/main.cpp index 2d8073da..b6dcf5f0 100644 --- a/scwx-qt/source/scwx/qt/main/main.cpp +++ b/scwx-qt/source/scwx/qt/main/main.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -129,6 +130,9 @@ int main(int argc, char* argv[]) // Deinitialize application scwx::qt::manager::RadarProductManager::Cleanup(); + // Stop Qt Threads + scwx::qt::manager::ThreadManager::Instance().StopThreads(); + // Gracefully stop the io_context main loop work.reset(); threadPool.join(); diff --git a/scwx-qt/source/scwx/qt/manager/thread_manager.cpp b/scwx-qt/source/scwx/qt/manager/thread_manager.cpp new file mode 100644 index 00000000..8b12edb0 --- /dev/null +++ b/scwx-qt/source/scwx/qt/manager/thread_manager.cpp @@ -0,0 +1,83 @@ +#include +#include + +#include + +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace manager +{ + +static const std::string logPrefix_ = "scwx::qt::manager::thread_manager"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +class ThreadManager::Impl +{ +public: + explicit Impl() {} + ~Impl() {} + + std::mutex mutex_ {}; + + boost::unordered_flat_map threadMap_ {}; +}; + +ThreadManager::ThreadManager() : p(std::make_unique()) {} +ThreadManager::~ThreadManager() = default; + +QThread* ThreadManager::thread(const std::string& id, bool autoStart) +{ + std::unique_lock lock {p->mutex_}; + QThread* thread = nullptr; + + auto it = p->threadMap_.find(id); + if (it != p->threadMap_.cend()) + { + thread = it->second; + } + + if (thread == nullptr) + { + logger_->debug("Creating thread: {}", id); + + thread = new QThread(this); + p->threadMap_.insert_or_assign(id, thread); + + if (autoStart) + { + thread->start(); + } + } + + return thread; +} + +void ThreadManager::StopThreads() +{ + std::unique_lock lock {p->mutex_}; + + logger_->debug("Stopping threads"); + + for (auto& thread : p->threadMap_) + { + thread.second->quit(); + thread.second->deleteLater(); + } + + p->threadMap_.clear(); +} + +ThreadManager& ThreadManager::Instance() +{ + static ThreadManager threadManager_ {}; + return threadManager_; +} + +} // namespace manager +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/manager/thread_manager.hpp b/scwx-qt/source/scwx/qt/manager/thread_manager.hpp new file mode 100644 index 00000000..496d30ba --- /dev/null +++ b/scwx-qt/source/scwx/qt/manager/thread_manager.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include + +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace manager +{ + +class ThreadManager : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY_MOVE(ThreadManager) + +public: + explicit ThreadManager(); + ~ThreadManager(); + + QThread* thread(const std::string& id, bool autoStart = true); + + void StopThreads(); + + static ThreadManager& Instance(); + +private: + class Impl; + std::unique_ptr p; +}; + +} // namespace manager +} // namespace qt +} // namespace scwx