114 lines
3.4 KiB
C++
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
|