NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
io_context.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_ASYNC_IO_CONTEXT_HPP__
2#define NEFORCE_CORE_ASYNC_IO_CONTEXT_HPP__
3
18
25NEFORCE_BEGIN_NAMESPACE__
26
32
38
40NEFORCE_INLINE17 constexpr uint32_t epoll_in = 0x001;
42NEFORCE_INLINE17 constexpr uint32_t epoll_out = 0x004;
44NEFORCE_INLINE17 constexpr uint32_t epoll_et = 0x80000000;
45
64class NEFORCE_API io_context {
65public:
67 using handler_type = function<void()>;
69 using fd_callback = function<void(int fd, uint32_t events, error_code ec)>;
71 using timer_callback = function<void()>;
72
74#ifdef NEFORCE_PLATFORM_WINDOWS
75 uintptr_t;
76#else
77 int;
78#endif
79
80 class executor;
81 class work;
82
87
94
95 io_context(const io_context&) = delete;
96 io_context& operator=(const io_context&) = delete;
97
102
107 void post(handler_type handler);
108
113 void dispatch(handler_type handler);
114
122 size_t run();
123
130 void run_pool(size_t n);
131
137 size_t run_one(int timeout_ms = -1);
138
143 size_t poll();
144
149 size_t poll_one() { return run_one(0); }
150
156 void stop();
157
161 bool stopped() const noexcept { return stopped_.load(memory_order_acquire); }
162
166 void restart() { stopped_.store(false, memory_order_release); }
167
174 size_t schedule_timer(uint64_t delay_ms, timer_callback handler);
175
181 bool cancel_timer(size_t timer_id);
182
190 void add_fd(native_handle_type fd, uint32_t events, fd_callback cb, bool edge_triggered = true);
191
198 void mod_fd(native_handle_type fd, uint32_t events, bool edge_triggered = true);
199
205
206private:
207 friend class file_async;
208
209 using file_completion_cb = function<void(error_code, size_t, void* overlapped)>;
210
212 struct timer_entry {
213 size_t id;
214 uint64_t deadline_ms;
215 timer_callback callback;
216 bool operator>(const timer_entry& other) const { return deadline_ms > other.deadline_ms; }
217 };
218
220 struct fd_info {
221 native_handle_type fd;
222 uint32_t events;
223 fd_callback callback;
224 };
225
227 atomic<int> running_{0};
229 atomic<bool> stopped_{false};
231 atomic<size_t> outstanding_work_{0};
233 size_t next_timer_id_{1};
234
236 flat_unordered_map<native_handle_type, fd_info> fd_map_;
238 vector<timer_entry> timer_heap_;
240 mutable mutex timer_mutex_;
241
243 lock_free_queue<handler_type> external_queue_;
245 atomic<size_t> external_queue_count_{0};
246
247#ifdef NEFORCE_PLATFORM_WINDOWS
249 void* iocp_handle_;
251 void* wake_event_;
253 flat_unordered_map<native_handle_type, void*> fd_events_;
255 mutex fd_mutex_;
257 thread monitor_thread_;
259 atomic<bool> monitor_running_{false};
260
262 flat_unordered_map<uintptr_t, file_completion_cb> file_completions_;
263
264 void monitor_loop();
265
266 void register_file_completion(uintptr_t key, file_completion_cb cb);
267 void unregister_file_completion(uintptr_t key);
268#else
270 int epoll_fd_;
272 int wake_fd_;
273#endif
274
276 vector<thread> pool_threads_;
278 mutex pool_mutex_;
279
281 uint64_t next_timer_deadline() const;
282
285 void process_timers(size_t max_count = numeric_traits<size_t>::max());
286
288 void wake();
289
292 size_t drain_handlers(size_t max_count = 256);
293};
294
303public:
304 executor(const executor& other) noexcept = default;
305 executor& operator=(const executor& other) noexcept = default;
306
310 void execute(handler_type handler) const { ctx_->post(move(handler)); }
311
315 NEFORCE_NODISCARD io_context& context() const noexcept { return *ctx_; }
316
320 bool operator==(const executor& other) const noexcept { return ctx_ == other.ctx_; }
321
325 bool operator!=(const executor& other) const noexcept { return ctx_ != other.ctx_; }
326
327private:
328 friend class io_context;
329
330 executor(io_context& ctx) noexcept :
331 ctx_(&ctx) {}
332
333 io_context* ctx_;
334};
335
347private:
348 io_context* ctx_;
349
350public:
354 explicit work(io_context& ctx) :
355 ctx_(&ctx) {
356 ctx_->outstanding_work_.fetch_add(1, memory_order_relaxed);
357 }
358
362 ~work() { ctx_->outstanding_work_.fetch_sub(1, memory_order_relaxed); }
363
364 work(const work&) = delete;
365 work& operator=(const work&) = delete;
366};
367 // IOContext
369 // AsyncComponents
371
372NEFORCE_END_NAMESPACE__
373#endif // NEFORCE_CORE_ASYNC_IO_CONTEXT_HPP__
函数包装器主模板声明
io_context 的执行器句柄
void execute(handler_type handler) const
在关联的 io_context 上投递 handler
io_context & context() const noexcept
获取关联的 io_context
bool operator!=(const executor &other) const noexcept
不等比较
bool operator==(const executor &other) const noexcept
相等比较 — 同一 io_context 的执行器相等
阻止 io_context::run() 提前退出的守卫
work(io_context &ctx)
构造函数 — 增加 io_context 的工作计数
~work()
析构函数 — 减少工作计数
统一异步操作核心
void run_pool(size_t n)
多线程并发驱动事件循环
size_t run()
单线程阻塞驱动事件循环
size_t run_one(int timeout_ms=-1)
等待并执行一个就绪的 handler
size_t poll()
执行所有已就绪的 handler 后立即返回
function< void()> timer_callback
定时器到期回调
uintptr_t native_handle_type
平台原生句柄类型
bool cancel_timer(size_t timer_id)
取消待执行的定时器
void remove_fd(native_handle_type fd)
取消 fd 的事件监控
void post(handler_type handler)
将 handler 投递到队列末尾
void mod_fd(native_handle_type fd, uint32_t events, bool edge_triggered=true)
修改已注册 fd 的事件掩码
size_t schedule_timer(uint64_t delay_ms, timer_callback handler)
调度一次性定时器
size_t poll_one()
非阻塞单次轮询
io_context()
构造 io_context
void restart()
重置停止标志,允许再次 run()
void add_fd(native_handle_type fd, uint32_t events, fd_callback cb, bool edge_triggered=true)
注册 fd 进行事件监控
function< void(int fd, uint32_t events, error_code ec)> fd_callback
fd 事件回调,参数为 (fd, events, error_code)
function< void()> handler_type
通用 handler 类型
executor get_executor() noexcept
获取默认执行器
void dispatch(handler_type handler)
若当前在 io_context 线程上则立即执行 handler,否则 post
void stop()
停止事件循环
bool stopped() const noexcept
检查是否已停止
平坦无序映射容器
通用函数包装器
unsigned int uint32_t
32位无符号整数类型
unsigned long uint64_t
64位无符号整数类型
constexpr uint32_t epoll_out
监控可写事件
constexpr uint32_t epoll_et
边沿触发模式
constexpr uint32_t epoll_in
监控可读事件
constexpr auto memory_order_release
释放内存顺序常量
constexpr auto memory_order_acquire
获取内存顺序常量
constexpr auto memory_order_relaxed
宽松内存顺序常量
uint64_t uintptr_t
可容纳指针的无符号整数类型
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
共享智能指针实现
动态大小数组容器