/* UsenetSearch 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. UsenetSearch 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 UsenetSearch. If not, see . */ #include "usenetsearch/ThreadPool.h" #include #include namespace usenetsearch { ThreadPool::ThreadPool() { m_threadStates = std::make_shared(); } ThreadPool::~ThreadPool() { m_stopping = true; JoinThreads(); } void ThreadPool::JoinThreads() { std::lock_guard threadsLock(m_threadsMutex); std::lock_guard threadStatesLock(m_threadStatesMutex); for (auto& thread: m_threads) { if (thread->joinable()) thread->join(); } m_threads.clear(); m_threadStates->clear(); } void ThreadPool::MaxThreads(std::uint16_t max) { m_maxThreads = max; } void ThreadPool::Queue(std::function fn) { if (m_stopping == true) return; // not accepting new work. if (m_maxThreads <= 1) { // single threaded case. fn(); return; } // Wait for an available thread. while (m_threads.size() >= m_maxThreads) { auto foundThread = m_threads.end(); for (auto it = m_threads.begin(); it != m_threads.end(); ++it) { const auto& t = (*it); if (!t) continue; if (t->joinable()) t->join(); foundThread = it; break; } if (foundThread != m_threads.end()) m_threads.erase(foundThread); } // Spawn a new thread. auto thread = std::make_unique(fn); m_threads.emplace_back(std::move(thread)); } } // namespace usenetsearch