pica/taskmanager/manager.cpp

70 lines
1.3 KiB
C++

//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#include "manager.h"
TM::Manager::Manager ():
terminating(false),
threads(),
queue(),
mtx(),
cond()
{}
TM::Manager::~Manager () {
std::unique_lock lock(mtx);
if (threads.empty())
return;
lock.unlock();
stop();
}
void TM::Manager::start () {
std::lock_guard lock(mtx);
std::size_t amount = std::thread::hardware_concurrency();
for (std::size_t i = 0; i < amount; ++i)
threads.emplace_back(std::thread(&Manager::loop, this));
}
void TM::Manager::stop () {
std::unique_lock lock(mtx);
terminating = true;
lock.unlock();
cond.notify_all();
for (std::thread& thread : threads)
thread.join();
lock.lock();
threads.clear();
terminating = false;
}
void TM::Manager::loop () {
while (true) {
std::unique_lock lock(mtx);
while (!terminating && queue.empty())
cond.wait(lock);
if (terminating)
return;
std::unique_ptr<Job> job = std::move(queue.front());
queue.pop();
lock.unlock();
job->execute();
}
}
void TM::Manager::schedule (std::unique_ptr<Job> job) {
std::unique_lock lock(mtx);
queue.emplace(std::move(job));
lock.unlock();
cond.notify_one();
}