LogIt++
Loading...
Searching...
No Matches
TaskExecutor.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _LOGIT_TASK_EXECUTOR_HPP_INCLUDED
3#define _LOGIT_TASK_EXECUTOR_HPP_INCLUDED
4
7
8#include <thread>
9#include <queue>
10#include <mutex>
11#include <functional>
12#include <condition_variable>
13#include <iostream>
14
15namespace logit {
16
17#if defined(__EMSCRIPTEN__)
18
21 class TaskExecutor {
22 public:
23 static TaskExecutor& get_instance() {
24 static TaskExecutor instance;
25 return instance;
26 }
27
28 void add_task(std::function<void()> task) {
29 if (task) task();
30 }
31
32 void wait() {}
33 void shutdown() {}
34
35 private:
36 TaskExecutor() = default;
37 ~TaskExecutor() = default;
38 TaskExecutor(const TaskExecutor&) = delete;
39 TaskExecutor& operator=(const TaskExecutor&) = delete;
40 TaskExecutor(TaskExecutor&&) = delete;
42 };
43
44#else
45
52 public:
56 static TaskExecutor* instance = new TaskExecutor();
57 return *instance;
58 }
59
62 void add_task(std::function<void()> task) {
63 std::unique_lock<std::mutex> lock(m_queue_mutex);
64 if (m_stop_flag) return;
65 m_tasks_queue.push(std::move(task));
66 lock.unlock();
67 m_queue_condition.notify_one();
68 }
69
71 void wait() {
72 m_queue_condition.notify_one();
73 for (;;) {
74 std::unique_lock<std::mutex> lock(m_queue_mutex);
75 if (m_tasks_queue.empty() || m_stop_flag) break;
76 lock.unlock();
77 std::this_thread::yield();
78 std::this_thread::sleep_for(std::chrono::milliseconds(1));
79 }
80 }
81
84 void shutdown() {
85 std::unique_lock<std::mutex> lock(m_queue_mutex);
86 m_stop_flag = true;
87 lock.unlock();
88 m_queue_condition.notify_one();
89 if (m_worker_thread.joinable()) {
90 m_worker_thread.join();
91 }
92 }
93
94 private:
95 std::queue<std::function<void()>> m_tasks_queue;
96 mutable std::mutex m_queue_mutex;
97 std::condition_variable m_queue_condition;
98 std::thread m_worker_thread;
100
103 for (;;) {
104 std::function<void()> task;
105 std::unique_lock<std::mutex> lock(m_queue_mutex);
106 m_queue_condition.wait(lock, [this]() {
107 return !m_tasks_queue.empty() || m_stop_flag;
108 });
109 if (m_stop_flag && m_tasks_queue.empty()) {
110 break;
111 }
112 task = std::move(m_tasks_queue.front());
113 m_tasks_queue.pop();
114 lock.unlock();
115 task();
116 }
117 }
118
122 }
123
126 shutdown();
127 }
128
129 // Delete copy constructor and assignment operators to enforce singleton usage.
130 TaskExecutor(const TaskExecutor&) = delete;
134 };
135
136#endif // defined(__EMSCRIPTEN__)
137
138}; // namespace logit
139
140#endif // _LOGIT_TASK_EXECUTOR_HPP_INCLUDED
void add_task(std::function< void()> task)
Adds a task to the queue in a thread-safe manner.
std::mutex m_queue_mutex
Mutex to protect access to the task queue.
~TaskExecutor()
Destructor that stops the worker thread and cleans up resources.
void shutdown()
Shuts down the TaskExecutor by stopping the worker thread.
TaskExecutor(TaskExecutor &&)=delete
bool m_stop_flag
Flag indicating if the worker thread should stop.
TaskExecutor(const TaskExecutor &)=delete
std::queue< std::function< void()> > m_tasks_queue
Queue holding tasks to be executed.
TaskExecutor & operator=(TaskExecutor &&)=delete
void wait()
Waits for all tasks in the queue to be processed.
TaskExecutor & operator=(const TaskExecutor &)=delete
std::thread m_worker_thread
Worker thread for executing tasks.
void worker_function()
The worker thread function that processes tasks from the queue.
static TaskExecutor & get_instance()
Get the singleton instance of the TaskExecutor.
std::condition_variable m_queue_condition
Condition variable to signal task availability.
TaskExecutor()
Private constructor to enforce the singleton pattern.
The primary namespace for the LogIt++ library.