80 lines
2.1 KiB
C++
80 lines
2.1 KiB
C++
/*
|
|
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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "usenetsearch/ThreadPool.h"
|
|
|
|
#include <memory>
|
|
#include <mutex>
|
|
|
|
namespace usenetsearch {
|
|
|
|
ThreadPool::ThreadPool()
|
|
{
|
|
m_threadStates = std::make_shared<ThreadStates>();
|
|
}
|
|
|
|
ThreadPool::~ThreadPool()
|
|
{
|
|
m_stopping = true;
|
|
JoinThreads();
|
|
}
|
|
|
|
void ThreadPool::JoinThreads()
|
|
{
|
|
std::lock_guard<std::mutex> threadsLock(m_threadsMutex);
|
|
std::lock_guard<std::mutex> 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<void()> 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<std::thread>(fn);
|
|
m_threads.emplace_back(std::move(thread));
|
|
}
|
|
|
|
} // namespace usenetsearch
|