-
Notifications
You must be signed in to change notification settings - Fork 0
/
thread.h
182 lines (139 loc) · 5.71 KB
/
thread.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#ifndef __THREAD_H__
#define __THREAD_H__
#include <boost/asio.hpp>
#include <thread>
#include <functional>
#include <queue>
#include <mutex>
#include <map>
#include <future>
#define MUTEX_GUARD(x) auto __gd = std::lock_guard(x);
using namespace std::chrono_literals;
namespace fb {
using thread_callback = std::function<void(std::chrono::steady_clock::duration, std::thread::id)> ;
using queue_callback = std::function<void(uint8_t)>;
class thread;
class timer
{
public:
friend class fb::thread;
public:
const fb::thread_callback fn;
const std::chrono::steady_clock::time_point begin;
const std::chrono::steady_clock::duration duration;
private:
timer(fb::thread_callback fn, std::chrono::steady_clock::duration duration);
timer(const timer&) = delete;
timer(timer&&) = delete;
timer& operator = (timer&) = delete;
timer& operator = (const timer&) = delete;
public:
~timer();
};
class queue : private std::queue<fb::queue_callback>
{
private:
std::mutex _mutex;
public:
queue() = default;
~queue() = default;
queue(const queue&) = delete;
queue(queue&&) = delete;
queue& operator = (queue&) = delete;
queue& operator = (const queue&) = delete;
public:
bool empty();
void enqueue(fb::queue_callback fn);
fb::queue_callback dequeue();
bool dequeue(fb::queue_callback& fn);
void flush(uint8_t index);
};
class thread
{
private:
uint8_t _index = 0;
bool _exit = false;
std::thread _thread;
private:
std::vector<std::shared_ptr<timer>> _timers;
std::mutex _mutex_timer;
public:
fb::queue queue, precedence;
public:
thread(uint8_t index);
~thread();
thread(const thread&) = delete;
thread(thread&&) = delete;
thread& operator = (thread&) = delete;
thread& operator = (const thread&) = delete;
private:
void handle_thread(uint8_t index);
void handle_idle();
public:
std::thread::id id() const;
uint8_t index() const;
void exit();
public:
void dispatch(const std::function<void()>& fn, const std::chrono::steady_clock::duration& duration);
void settimer(fb::thread_callback fn, const std::chrono::steady_clock::duration& duration);
public:
static std::chrono::steady_clock::duration now();
};
class async
{
private:
static std::unique_ptr<async> _ist;
private:
std::thread _async_thread;
std::vector<std::future<void>> _futures;
bool _exit;
std::mutex _async_mutex;
public:
async();
~async();
private:
void _launch(const std::function<void()>& fn);
void async_handler();
static async* get();
public:
static void launch(const std::function<void()>& fn);
static void exit();
};
class threads
{
public:
using unique_thread = std::unique_ptr<fb::thread>;
using unique_threads = std::map<std::thread::id, unique_thread>;
using unique_id_list = std::unique_ptr<std::thread::id[]>;
private:
boost::asio::io_context& _context;
unique_threads _threads;
unique_id_list _keys;
public:
threads(boost::asio::io_context& context, uint8_t count);
~threads() = default;
threads(const threads&) = delete;
threads(threads&&) = delete;
threads& operator = (threads&) = delete;
threads& operator = (const threads&) = delete;
public:
fb::thread* at(uint8_t index) const;
fb::thread* at(std::thread::id id) const;
fb::thread* current();
const fb::thread* current() const;
uint8_t count() const;
bool empty() const;
bool valid(uint8_t index) const;
bool valid(fb::thread* thread) const;
bool valid(fb::thread& thread) const;
size_t size() const;
public:
void dispatch(const std::function<void()>& fn, const std::chrono::steady_clock::duration& duration, bool main = false);
void settimer(fb::thread_callback fn, const std::chrono::steady_clock::duration& duration);
void exit();
public:
fb::thread* operator [] (uint8_t index) const;
fb::thread* operator [] (std::thread::id id) const;
};
}
#endif // !__THREAD_H__