pica/taskmanager/scheduler.cpp

78 lines
1.7 KiB
C++
Raw Normal View History

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();
}