UsenetSearch/src/ThreadPool.cpp

114 lines
3.4 KiB
C++

#include "usenetsearch/ThreadPool.h"
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)
{
//std::lock_guard<std::mutex> threadsLock(m_threadsMutex);
auto foundThread = m_threads.end();
//auto foundStatus = m_threadStates->end();
for (auto it = m_threads.begin(); it != m_threads.end(); ++it)
{
const auto& t = (*it);
if (!t) continue;
//const auto threadID = t->get_id();
//if (threadID == std::thread::id{}) continue;
//ThreadStates::iterator statusIt;
//{
// std::lock_guard<std::mutex> tsl(m_threadStatesMutex);
// statusIt = m_threadStates->find(threadID);
//}
//if (statusIt == m_threadStates->end()) continue;
//bool state = statusIt->second;
//if (state == true)
//{
if (t->joinable()) t->join();
foundThread = it;
// foundStatus = statusIt;
break;
//}
}
if (foundThread != m_threads.end()) m_threads.erase(foundThread);
/*
{
std::lock_guard<std::mutex> tsl(m_threadStatesMutex);
if (foundStatus != m_threadStates->end()) m_threadStates->erase(foundStatus);
}
*/
}
// Spawn a new thread.
auto thread = std::make_unique<std::thread>(fn);
/*
auto thread = std::make_unique<std::thread>(
[](std::function<void()> func, std::mutex& tsm, std::shared_ptr<ThreadStates> ts)
{
if (ts == nullptr) return;
{
std::lock_guard<std::mutex> tsl(tsm);
const auto threadID = std::this_thread::get_id();
if (threadID == std::thread::id{}) return;
ts->emplace(threadID, false);
}
func();
{
std::lock_guard<std::mutex> tsl(tsm);
const auto threadID = std::this_thread::get_id();
if (threadID != std::thread::id{})
{
auto it = ts->find(threadID);
if (it == ts->end())
{
ts->emplace(threadID, true);
}
else
{
(*ts)[threadID] = true;
}
}
}
}, fn, std::ref(m_threadStatesMutex), m_threadStates);
*/
//std::lock_guard<std::mutex> threadsLock(m_threadsMutex);
m_threads.emplace_back(std::move(thread));
}
} // namespace usenetsearch