beginning of the scheduler
This commit is contained in:
parent
f1a2006b4b
commit
26114aad5f
6 changed files with 157 additions and 0 deletions
|
@ -5,12 +5,14 @@ set(HEADERS
|
|||
manager.h
|
||||
job.h
|
||||
route.h
|
||||
scheduler.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
manager.cpp
|
||||
job.cpp
|
||||
route.cpp
|
||||
scheduler.cpp
|
||||
)
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})
|
||||
|
|
75
taskmanager/scheduler.cpp
Normal file
75
taskmanager/scheduler.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
//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):
|
||||
manager(manager),
|
||||
queue(),
|
||||
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;
|
||||
}
|
||||
|
||||
Task task = queue.top().second;
|
||||
queue.pop();
|
||||
lock.unlock();
|
||||
task();
|
||||
lock.lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TM::Scheduler::schedule (Task task, Delay delay) {
|
||||
std::unique_lock lock(mutex);
|
||||
Time time = std::chrono::steady_clock::now() + delay;
|
||||
queue.emplace(time, task);
|
||||
|
||||
lock.unlock();
|
||||
cond.notify_one();
|
||||
}
|
48
taskmanager/scheduler.h
Normal file
48
taskmanager/scheduler.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
//SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||
//SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "manager.h"
|
||||
#include "utils/helpers.h"
|
||||
|
||||
namespace TM {
|
||||
class Scheduler {
|
||||
public:
|
||||
using Delay = std::chrono::milliseconds;
|
||||
using Task = std::function<void()>;
|
||||
|
||||
Scheduler (std::weak_ptr<Manager> manager);
|
||||
~Scheduler ();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void schedule(Task task, Delay delay);
|
||||
|
||||
private:
|
||||
void loop();
|
||||
|
||||
private:
|
||||
using Time = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
using Record = std::pair<Time, Task>;
|
||||
|
||||
std::weak_ptr<Manager> manager;
|
||||
std::priority_queue<
|
||||
Record,
|
||||
std::vector<Record>,
|
||||
FirstGreater<Record>
|
||||
> queue;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cond;
|
||||
std::unique_ptr<std::thread> thread;
|
||||
bool running;
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue