/* * This file is part of the Flowee project * Copyright (C) 2016-2025 Tom Zander * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "WorkerThreads.h" #include "Logger.h" WorkerThreads::Work::Work(const std::shared_ptr &context) : work(boost::asio::make_work_guard(*context)) { } // ------------------------------------ WorkerThreads::WorkerThreads(int threadCount) { startThreads(threadCount); } void WorkerThreads::startThreads(int threadCount) { if (threadCount < 1) threadCount = boost::thread::hardware_concurrency(); threadCount = std::max(threadCount, 2); m_context = std::make_shared(); m_work.reset(new Work(m_context)); for (int i = threadCount; i > 0; --i) { auto context(m_context); m_threads.create_thread([context] { #if defined(PR_SET_NAME) // Only the first 15 characters are used (16 - NUL terminator) ::prctl(PR_SET_NAME, "Worker-threads", 0, 0, 0); #endif while(true) { try { context->run(); return; } catch (const boost::thread_interrupted&) { return; } catch (const std::exception& ex) { logCritical(Log::Flowee) << "Threadgroup: uncaught exception" << ex; } } }); } } WorkerThreads::~WorkerThreads() { stopThreads(); joinAll(); } void WorkerThreads::stopThreads() { m_work.reset(); if (m_context.get()) // it gets reset() by joinAll m_context->stop(); } void WorkerThreads::joinAll() { m_threads.join_all(); m_context.reset(); // tasks don't get garbage-collected until the destructor is ran } boost::asio::io_context& WorkerThreads::ioContext() const { return *m_context; }