2023-12-31 17:10:04 +00:00
|
|
|
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
|
|
|
//SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
|
|
#include "scheduler.h"
|
|
|
|
|
|
|
|
TM::Scheduler::Scheduler (std::weak_ptr<Manager> manager):
|
|
|
|
queue(),
|
2024-01-03 01:11:56 +00:00
|
|
|
manager(manager),
|
2023-12-31 17:10:04 +00:00
|
|
|
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<std::thread>(&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<std::mutex> 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;
|
|
|
|
}
|
|
|
|
|
2024-01-03 01:11:56 +00:00
|
|
|
Record task = queue.pop();
|
2023-12-31 17:10:04 +00:00
|
|
|
lock.unlock();
|
2024-01-03 01:11:56 +00:00
|
|
|
std::shared_ptr<Manager> mngr = manager.lock();
|
|
|
|
if (mngr)
|
|
|
|
mngr->schedule(std::move(task.second));
|
|
|
|
|
2023-12-31 17:10:04 +00:00
|
|
|
lock.lock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-03 01:11:56 +00:00
|
|
|
void TM::Scheduler::schedule (const std::function<void()>& task, Delay delay) {
|
2023-12-31 17:10:04 +00:00
|
|
|
std::unique_lock lock(mutex);
|
|
|
|
Time time = std::chrono::steady_clock::now() + delay;
|
2024-01-03 01:11:56 +00:00
|
|
|
queue.emplace(time, std::make_unique<Function>(task));
|
2023-12-31 17:10:04 +00:00
|
|
|
|
|
|
|
lock.unlock();
|
|
|
|
cond.notify_one();
|
|
|
|
}
|