1
0
Fork 0
mirror of https://gitlab.com/niansa/cosched.git synced 2025-03-06 20:53:26 +01:00
cosched/include/scheduled_thread.hpp
2023-05-05 18:43:27 +02:00

76 lines
1.7 KiB
C++

#ifndef SCHEDULED_THREAD_HPP
#define SCHEDULED_THREAD_HPP
#include "scheduler.hpp"
#include <functional>
#include <future>
#include <mutex>
#include <queue>
#include <thread>
namespace CoSched {
class ScheduledThread {
static thread_local ScheduledThread *current;
struct QueueEntry {
std::string task_name;
std::function<AwaitableTask<void> ()> start_fcn;
};
std::thread thread;
std::mutex queue_mutex;
std::queue<QueueEntry> queue;
std::mutex conditional_mutex;
std::condition_variable conditional_lock;
bool shutdown_requested = false;
bool joined = false;
void main_loop();
public:
ScheduledThread() {}
// Current thread MUST be made by start()
inline static
ScheduledThread *get_current() {
return current;
}
// MUST NOT already be running
void start() {
thread = std::thread([this] () {
current = this;
main_loop();
});
}
// Can be called from anywhere
void create_task(const std::string& task_name, std::function<AwaitableTask<void> ()>&& task_fcn) {
// Enqueue function
{
std::scoped_lock L(queue_mutex);
queue.emplace(QueueEntry{task_name, std::move(task_fcn)});
}
// Notify thread
conditional_lock.notify_one();
}
// MUST already be running
void wait() {
joined = true;
thread.join();
}
// MUST already be running
void shutdown() {
create_task("Shutdown Initiator", [this] () -> AwaitableTask<void> {
shutdown_requested = true;
co_return;
});
}
};
}
#endif // SCHEDULED_THREAD_HPP