//SPDX-FileCopyrightText: 2023 Yury Gubich //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 = std::move(queue.front()); queue.pop(); lock.unlock(); job->execute(); } } void TM::Manager::schedule (std::unique_ptr job) { std::unique_lock lock(mtx); queue.emplace(std::move(job)); lock.unlock(); cond.notify_one(); }