Skip to content

Commit b6c3fe9

Browse files
committed
feat: add asio adaptor
1 parent ad6f3d5 commit b6c3fe9

File tree

9 files changed

+1303
-104
lines changed

9 files changed

+1303
-104
lines changed

.github/workflows/ci.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,12 @@ jobs:
8787
steps:
8888
- uses: actions/checkout@v4
8989

90+
- name: Init ASIO
91+
run: git clone https://github.com/chriskohlhoff/asio.git -b asio-1-32-0 --depth=1
92+
9093
- name: Configure ${{ matrix.build_type }} disable_exception:${{ matrix.disable_exception }} sanitize_address:${{ matrix.sanitize_address }} sanitize_thread:${{ matrix.sanitize_thread }}
94+
env:
95+
ASIO_PATH: asio/asio/include
9196
run: |
9297
cmake -S . -B build \
9398
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
@@ -206,3 +211,9 @@ jobs:
206211
working-directory: build
207212
run: |
208213
./coro_coro_local${{ matrix.env.BIN_SUFFIX }}
214+
215+
- name: Test asio_adaptor
216+
if: always()
217+
working-directory: build
218+
run: |
219+
./coro_asio_adaptor${{ matrix.env.BIN_SUFFIX }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/.idea/
22
/build/
3+
/build_*/
34
/cmake-build-*/

AGENTS.md

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
# AGENTS.md
2+
3+
AI 编程助手在本 C++20 协程库中的开发指南。
4+
5+
## 项目概述
6+
7+
**coro** 是一个轻量级、仅头文件的 C++20 协程库,提供异步任务、同步原语和并发控制。设计目标:简洁、跨平台(包括嵌入式/MCU)、可选的无异常模式。
8+
9+
## 构建命令
10+
11+
```bash
12+
# 标准构建
13+
cmake -S . -B build && cmake --build build -j
14+
15+
# 启用 AddressSanitizer
16+
cmake -S . -B build -DCORO_ENABLE_SANITIZE_ADDRESS=ON && cmake --build build
17+
18+
# 启用 ThreadSanitizer
19+
cmake -S . -B build -DCORO_ENABLE_SANITIZE_THREAD=ON && cmake --build build
20+
21+
# 禁用异常(用于嵌入式平台)
22+
cmake -S . -B build -DCORO_DISABLE_EXCEPTION=ON && cmake --build build
23+
```
24+
25+
默认使用`build`文件夹,特殊构建时,可使用`build_asan``build_release`文件夹。
26+
27+
## 运行测试
28+
29+
每个测试是独立的可执行文件,在 build 目录下运行:
30+
31+
```bash
32+
./coro_task # 核心异步任务测试
33+
./coro_mutex # 互斥锁测试
34+
./coro_channel # 通道测试
35+
./coro_when # when_all/when_any 测试
36+
./coro_semaphore # 信号量测试
37+
./coro_condition_variable # 条件变量测试
38+
./coro_wait_group # 等待组测试
39+
./coro_latch # 闩锁测试
40+
./coro_event # 事件测试
41+
./coro_broadcast # 通道广播测试
42+
./coro_task_verbose # 带生命周期日志的任务测试
43+
./coro_multi_thread # 多线程测试
44+
./coro_multi_thread_st # 多线程测试(单线程模式)
45+
```
46+
47+
**无测试框架** - 测试使用自定义 `ASSERT()` 宏和 `LOG()` 输出。测试通过的标志是退出码为 0。
48+
49+
## 代码风格
50+
51+
### 格式化
52+
53+
- **clang-format**:基于 Google 风格,150 列宽限制
54+
- 提交前运行:`clang-format -i <文件>`
55+
- 短函数/lambda:仅空函数体可单行
56+
57+
### 命名规范
58+
59+
- **命名空间**`coro`,内部实现用 `coro::detail`
60+
- **类型**`snake_case`(如 `mutex_t``awaitable_promise``counting_semaphore_t`
61+
- **类型别名**`snake_case`(如 `using mutex = mutex_t;`
62+
- **函数/方法**`snake_case`(如 `scoped_lock()``await_ready()`
63+
- **成员变量**`snake_case_` 带尾部下划线(如 `counter_``mutex_`
64+
- **模板参数**`UPPER_CASE`(如 `MUTEX``T`
65+
- ****`UPPER_CASE` 带前缀(如 `CORO_DEBUG_PROMISE_LEAK`
66+
67+
### 头文件包含顺序
68+
69+
1. 配置/调试宏(在库头文件之前)
70+
2. 标准库头文件(`<coroutine>``<atomic>` 等)
71+
3. 项目头文件(`"coro/coro.hpp"``"coro/executor.hpp"`
72+
73+
### 类型设计模式
74+
75+
- **模板互斥锁参数**:使用 `typename MUTEX = std::mutex` 控制线程安全
76+
- **类型别名**:提供 `_mt`(多线程)和 `_st`(单线程)变体
77+
- **可等待类型**:嵌套结构体命名为 `*_awaitable`(如 `lock_awaitable``send_awaitable`
78+
79+
### 协程模式
80+
81+
- 返回类型:`async<T>``awaitable<T>` 的别名)
82+
- 使用 `co_await``co_return` 关键字
83+
- 延迟启动:协程在 `initial_suspend()` 处挂起
84+
- 执行器继承:子协程继承父协程的执行器
85+
- **协程 lambda 禁止捕获引用**:lambda 立即调用后销毁,捕获的引用会悬空,需用参数传递
86+
87+
```cpp
88+
async<int> example_coro() {
89+
co_await sleep(100ms);
90+
co_return 42;
91+
}
92+
93+
// 错误:lambda 销毁后捕获的引用悬空
94+
spawn(exec, [&counter]() -> async<void> {
95+
counter++; // 未定义行为
96+
}());
97+
98+
// 正确:通过参数传递
99+
spawn(exec, [](int& cnt) -> async<void> {
100+
cnt++;
101+
}(counter));
102+
```
103+
104+
### 错误处理
105+
106+
- **启用异常**(默认):在 promise 中使用 `std::exception_ptr`
107+
- **禁用异常**(`CORO_DISABLE_EXCEPTION`):返回值使用 `std::optional`
108+
- 两种路径都需要用 `#ifndef CORO_DISABLE_EXCEPTION` 保护
109+
110+
### 内存与生命周期
111+
112+
- 禁用拷贝,启用移动
113+
- 使用 RAII 守卫(如 `lock_guard`)管理资源
114+
- 使用侵入式链表管理等待队列(避免堆分配)
115+
116+
### 测试文件结构
117+
118+
```cpp
119+
#define CORO_DEBUG_PROMISE_LEAK
120+
#include "log.h"
121+
#include "TimeCount.hpp"
122+
#include "assert_def.h"
123+
#include "coro/coro.hpp"
124+
#include "utils.hpp"
125+
126+
using namespace coro;
127+
128+
async<void> test_feature() {
129+
ASSERT(condition);
130+
LOG("Test passed");
131+
}
132+
133+
int main() {
134+
LOG("Test init");
135+
executor_loop executor;
136+
test_feature().detach_with_callback(executor, [&] {
137+
executor.stop();
138+
});
139+
executor.run_loop();
140+
check_coro_leak(); // 验证无协程泄漏
141+
return 0;
142+
}
143+
```
144+
145+
## 核心 API
146+
147+
| 组件 | 用法 |
148+
|------------------------------|-----------------------------|
149+
| `async<T>` | 协程返回类型 |
150+
| `spawn(executor, coro)` | 启动分离的协程 |
151+
| `co_await mtx.scoped_lock()` | RAII 互斥锁 |
152+
| `co_await ch.send(val)` | 通道发送 |
153+
| `co_await ch.recv()` | 通道接收(返回 `std::optional<T>`|
154+
| `co_await sem.acquire()` | 信号量获取 |
155+
| `sem.release()` | 信号量释放(非阻塞) |
156+
| `when_all(...)` | 等待所有可等待对象 |
157+
| `when_any(...)` | 等待任意一个完成 |
158+
159+
## 调试宏
160+
161+
```cpp
162+
#define CORO_DEBUG_PROMISE_LEAK // 启用泄漏追踪
163+
#define CORO_DEBUG_LEAK_LOG LOG // 泄漏日志函数
164+
#define CORO_DEBUG_LIFECYCLE LOG // 协程生命周期日志
165+
```
166+
167+
测试结束时调用 `check_coro_leak()` 验证无泄漏。
168+
169+
## 添加新功能
170+
171+
添加新功能时需要同时更新三个文件:
172+
173+
### 1. CMakeLists.txt
174+
175+
在 `if (CORO_BUILD_TEST)` 块中添加:
176+
177+
```cmake
178+
set(TARGET_NAME ${PROJECT_NAME}_new_feature)
179+
add_executable(${TARGET_NAME} test/coro_new_feature.cpp)
180+
```
181+
182+
### 2. .github/workflows/ci.yml
183+
184+
在测试步骤部分添加:
185+
186+
```yaml
187+
- name: Test new_feature
188+
if: always()
189+
working-directory: build
190+
run: |
191+
./coro_new_feature${{ matrix.env.BIN_SUFFIX }}
192+
```
193+
194+
### 3. 创建测试文件 test/coro_new_feature.cpp
195+
196+
使用上述"测试文件结构"模板。
197+
198+
### 4. 补充文档,更新README.md和README_CN.md,放到同类功能后面
199+
200+
## 平台说明
201+
202+
- **编译器**:GCC、Clang、MSVC(需 `/Zc:preprocessor`)
203+
- **Windows**:添加 `-DNOMINMAX` 避免宏冲突
204+
- **嵌入式**:定义 `CORO_DISABLE_EXCEPTION` 用于不支持异常的平台

CLAUDE.md

Lines changed: 0 additions & 103 deletions
This file was deleted.

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,13 @@ if (CORO_BUILD_TEST)
137137
set(TARGET_NAME ${PROJECT_NAME}_coro_local)
138138
add_executable(${TARGET_NAME} test/coro_local.cpp)
139139
target_compile_definitions(${TARGET_NAME} PRIVATE -DCORO_ENABLE_LOCAL_STORAGE)
140+
141+
message(STATUS "ASIO_PATH: $ENV{ASIO_PATH}")
142+
# test asio adaptor (optional, requires asio)
143+
if (NOT "$ENV{ASIO_PATH}" STREQUAL "")
144+
add_definitions(-DASIO_NO_DEPRECATED)
145+
set(TARGET_NAME ${PROJECT_NAME}_asio_adaptor)
146+
add_executable(${TARGET_NAME} test/coro_asio_adaptor.cpp)
147+
target_include_directories(${TARGET_NAME} PRIVATE $ENV{ASIO_PATH})
148+
endif()
140149
endif ()

0 commit comments

Comments
 (0)