//SPDX-FileCopyrightText: 2023 Yury Gubich //SPDX-License-Identifier: GPL-3.0-or-later #include "scheduler.h" TM::Scheduler::Scheduler (std::weak_ptr manager): queue(), manager(manager), mutex(), cond(), thread(nullptr), running(false) {} TM::Scheduler::~Scheduler () { stop(); } void TM::Scheduler::start () { std::unique_lock lock(mutex); if (running) return; running = true; thread = std::make_unique(&Scheduler::loop, this); } void TM::Scheduler::stop () { std::unique_lock lock(mutex); if (!running) return; running = false; lock.unlock(); cond.notify_all(); thread->join(); lock.lock(); thread.reset(); } void TM::Scheduler::loop () { while (running) { std::unique_lock lock(mutex); if (queue.empty()) { cond.wait(lock); continue; } Time currentTime = std::chrono::steady_clock::now(); while (!queue.empty()) { Time nextScheduledTime = queue.top().first; if (nextScheduledTime > currentTime) { cond.wait_until(lock, nextScheduledTime); break; } Record task = queue.pop(); lock.unlock(); std::shared_ptr mngr = manager.lock(); if (mngr) mngr->schedule(std::move(task.second)); lock.lock(); } } } void TM::Scheduler::schedule (const std::function& task, Delay delay) { std::unique_lock lock(mutex); Time time = std::chrono::steady_clock::now() + delay; queue.emplace(time, std::make_unique(task)); lock.unlock(); cond.notify_one(); }