mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-11-04 05:10:06 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			97 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <scwx/qt/manager/thread_manager.hpp>
 | 
						|
#include <scwx/util/logger.hpp>
 | 
						|
 | 
						|
#include <execution>
 | 
						|
#include <mutex>
 | 
						|
 | 
						|
#include <boost/unordered/unordered_flat_map.hpp>
 | 
						|
#include <QThread>
 | 
						|
 | 
						|
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<std::string, QThread*> threadMap_ {};
 | 
						|
};
 | 
						|
 | 
						|
ThreadManager::ThreadManager() : p(std::make_unique<Impl>()) {}
 | 
						|
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");
 | 
						|
 | 
						|
   std::for_each(std::execution::par_unseq,
 | 
						|
                 p->threadMap_.begin(),
 | 
						|
                 p->threadMap_.end(),
 | 
						|
                 [](auto& thread)
 | 
						|
                 {
 | 
						|
                    logger_->trace("Stopping thread: {}", thread.first);
 | 
						|
 | 
						|
                    thread.second->quit();
 | 
						|
                    if (!thread.second->wait(5000))
 | 
						|
                    {
 | 
						|
                       logger_->warn("Terminating thread: {}", thread.first);
 | 
						|
 | 
						|
                       thread.second->terminate();
 | 
						|
                       thread.second->wait();
 | 
						|
                    }
 | 
						|
 | 
						|
                    delete thread.second;
 | 
						|
                 });
 | 
						|
 | 
						|
   p->threadMap_.clear();
 | 
						|
}
 | 
						|
 | 
						|
ThreadManager& ThreadManager::Instance()
 | 
						|
{
 | 
						|
   static ThreadManager threadManager_ {};
 | 
						|
   return threadManager_;
 | 
						|
}
 | 
						|
 | 
						|
} // namespace manager
 | 
						|
} // namespace qt
 | 
						|
} // namespace scwx
 |