scheduler canceling, sessiion query, didn't test yet!

This commit is contained in:
Blue 2024-01-03 19:20:01 -03:00
parent 544db92b6e
commit 5d765958e5
Signed by: blue
GPG key ID: 9B203B252A63EE38
15 changed files with 166 additions and 21 deletions

View file

@ -7,6 +7,7 @@ set(HEADERS
route.h
scheduler.h
function.h
record.h
)
set(SOURCES
@ -15,6 +16,7 @@ set(SOURCES
route.cpp
scheduler.cpp
function.cpp
record.cpp
)
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})

18
taskmanager/record.cpp Normal file
View file

@ -0,0 +1,18 @@
//SPDX-FileCopyrightText: 2024 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#include "record.h"
TM::Record::Record (ID id, const Task& task, Time time):
id(id),
task(task),
time(time)
{}
bool TM::Record::operator < (const Record& other) const {
return time < other.time;
}
bool TM::Record::operator > (const Record& other) const {
return time > other.time;
}

26
taskmanager/record.h Normal file
View file

@ -0,0 +1,26 @@
//SPDX-FileCopyrightText: 2024 Yury Gubich <blue@macaw.me>
//SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <cstdint>
#include <chrono>
#include <functional>
namespace TM {
class Record {
public:
using Time = std::chrono::time_point<std::chrono::steady_clock>;
using Task = std::function<void()>;
using ID = uint64_t;
Record(ID id, const Task& task, Time time);
ID id;
Task task;
Time time;
bool operator > (const Record& other) const;
bool operator < (const Record& other) const;
};
}

View file

@ -3,13 +3,17 @@
#include "scheduler.h"
const TM::Record::ID TM::Scheduler::none = 0;
TM::Scheduler::Scheduler (std::weak_ptr<Manager> manager):
queue(),
scheduled(),
manager(manager),
mutex(),
cond(),
thread(nullptr),
running(false)
running(false),
idCounter(TM::Scheduler::none)
{}
TM::Scheduler::~Scheduler () {
@ -50,28 +54,39 @@ void TM::Scheduler::loop () {
Time currentTime = std::chrono::steady_clock::now();
while (!queue.empty()) {
Time nextScheduledTime = queue.top().first;
Time nextScheduledTime = queue.top().time;
if (nextScheduledTime > currentTime) {
cond.wait_until(lock, nextScheduledTime);
break;
}
Record task = queue.pop();
Record record = queue.pop();
std::size_t count = scheduled.erase(record.id);
if (count == 0) //it means this record has been cancelled, no need to execute it
continue;
lock.unlock();
std::shared_ptr<Manager> mngr = manager.lock();
if (mngr)
mngr->schedule(std::move(task.second));
mngr->schedule(std::make_unique<Function>(record.task));
lock.lock();
}
}
}
void TM::Scheduler::schedule (const std::function<void()>& task, Delay delay) {
TM::Record::ID TM::Scheduler::schedule (const Task& task, Delay delay) {
std::unique_lock lock(mutex);
Time time = std::chrono::steady_clock::now() + delay;
queue.emplace(time, std::make_unique<Function>(task));
queue.emplace(++idCounter, task, time);
scheduled.emplace(idCounter);
lock.unlock();
cond.notify_one();
return idCounter;
}
bool TM::Scheduler::cancel (Record::ID id) {
return scheduled.erase(id) != 0; //not to mess with the queue, here we just mark it as not scheduled
} //and when the time comes it will be just discarded

View file

@ -6,43 +6,47 @@
#include <memory>
#include <thread>
#include <chrono>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <set>
#include "manager.h"
#include "function.h"
#include "record.h"
#include "utils/helpers.h"
namespace TM {
class Scheduler {
public:
using Delay = std::chrono::milliseconds;
using Time = Record::Time;
using Task = Record::Task;
Scheduler (std::weak_ptr<Manager> manager);
~Scheduler ();
void start();
void stop();
void schedule(const std::function<void()>& task, Delay delay);
void start ();
void stop ();
Record::ID schedule (const Task& task, Delay delay);
bool cancel (Record::ID id);
static const Record::ID none;
private:
void loop();
void loop ();
private:
using Task = std::unique_ptr<Function>;
using Time = std::chrono::time_point<std::chrono::steady_clock>;
using Record = std::pair<Time, Task>;
PriorityQueue<
Record,
std::vector<Record>,
FirstGreater<Record>
std::greater<>
> queue;
std::set<Record::ID> scheduled;
std::weak_ptr<Manager> manager;
std::mutex mutex;
std::condition_variable cond;
std::unique_ptr<std::thread> thread;
bool running;
Record::ID idCounter;
};
}