Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Hical61/Hical
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.6.4
Choose a base ref
...
head repository: Hical61/Hical
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v2.6.5
Choose a head ref
  • 8 commits
  • 46 files changed
  • 1 contributor

Commits on May 30, 2026

  1. Configuration menu
    Copy the full SHA
    3cc0f98 View commit details
    Browse the repository at this point in the history

Commits on Jun 2, 2026

  1. [fix] 连接数限制在 burst 建连时失效的问题

    原来的逻辑是先 load 判断,再在 handleSession 里 fetch_add。
    但 handleSession 是 coSpawn 异步投递的,高速建连时一堆连接
    已经 accept 了但计数还没跟上,限流等于白设。
    
    改成在 accept 处直接 fetch_add 占位,超限就 fetch_sub 退回来
    再 close socket。中间如果出什么意外,AcceptGuard 负责回退,
    不会有计数泄漏。
    
    另外顺手做了几件事:
    - maxConnections_ 换成 atomic,多 acceptor 并发安全
    - recommendedMaxConnections 推荐上限从 65535 放到 100 万
    - set_option 加上 error_code,失败不崩但有地方接着
    - .gitignore 补上 __pycache__ 和 *.pyc
    Hical61 committed Jun 2, 2026
    Configuration menu
    Copy the full SHA
    7ca70f1 View commit details
    Browse the repository at this point in the history

Commits on Jun 4, 2026

  1. [feat] 支持 Expect: 100-continue

    Router 加了 exists() 做路由预检,SessionImpl 解析 Expect 头,
    路由不存在直接 404,body 超限直接 413,都没问题再发 100 Continue 让客户端把 body 送过来。
    顺手加了一组集成测试。
    
    Closes #8
    Hical61 committed Jun 4, 2026
    Configuration menu
    Copy the full SHA
    feb9fba View commit details
    Browse the repository at this point in the history

Commits on Jun 9, 2026

  1. [perf] 空闲长连接内存优化:readBuf 借还 + PmrBuffer 懒分配

    长连接空闲时不再持有 readBuf,改成请求来了再借、写完了就还回去。空闲连接内存从 17.44 KB 砍到 8 KB 左右。
    
    主要改动:
    - 搞了个 ReadBufferPool(thread_local 无锁,BufferHandle RAII 析构自动归还)
    - HttpSessionImpl 改成请求来的时候借缓冲,响应写完归还;粘包残留用 pipelineSpill 暂存,下次借到新 buffer 再 memcpy 进去继续处理
    - pipeline spill 那边顺手修了下:initSize 取 max(spillSize, kBufferSize),保证两条路径初始缓冲大小一致,省得头部读取反复小步扩容
    
    顺便把 GenericConnection::inputBuffer_ 改成 optional<PmrBuffer> 懒分配,readLoop 第一次进来才 emplace,每个空闲连接又省了大概 2 KB。
    
    算了下收益(按百万空闲长连接算):
    - readBuf 借还:17.44 KB → ~10 KB,单连接省 7.5 KB,总共省 ~7.5 GB
    - 叠加 PmrBuffer 懒分配后:~10 KB → ~8 KB,再省 ~2 GB
    Hical61 committed Jun 9, 2026
    Configuration menu
    Copy the full SHA
    0cb47fb View commit details
    Browse the repository at this point in the history
  2. [fix] WS 升级路径堆损坏:readBuf/idleEntry 提前释放 + PoolSlots 析构泄漏

    这次修的是 readBuf 借还优化带进来的三个坑,都跟生命周期有关。
    
    第一个:PoolSlots 是 thread_local 的,但里面只是裸指针数组,没有
    析构函数。线程退出时池里剩的 string 对象直接就漏了,LeakSanitizer
    能抓到,Windows 全量跑的时候也会触发堆损坏。加个 ~PoolSlots() 在
    线程退出时把剩的全 delete 掉就行了。
    
    第二个:handleSession 里 readBufHandle 在 WS 升级后一直不归还,
    要等整个 WS 会话结束、协程帧析构才还回去。连接活着的时候没问题,
    但 server.stop() 触发 IOCP 两阶段协程帧销毁时,帧的析构可能晚于
    thread_local tlsPool 的析构,returnBuffer() 就写到已经释放的内存
    上去了。
    
    第三个:socket move 给 handleWebSocket 之后,handleSession 的
    idleEntry 还挂在 IdleScanner 链表上。这个指针指的是 moved-from
    的 socket,scanner 遍历过来调 close() 就直接踩坏堆了。
    
    统一的修法是在 socket move 之前把该收的都收掉:把握手用的头部字段
    拷成 owned string,做完验证,然后 readBufHandle.release()、
    idleGuard.release(),最后再 move socket 进 handleWebSocket。
    handleWebSocket 签名也跟着改成接受 string 参数,从根上断掉对
    readBuf 的引用。IdleScanner::Guard 加了个幂等的 release(),
    让提前注销这个操作有个明确的接口。
    
    顺带修了 OversizedBufferNotPooled 测试,原来是靠比较指针地址判断
    超大 buffer 有没有入池,glibc 会复用刚释放的内存,Linux 上经常拿
    到同一个地址,CI 偶发失败。改成先把池排空再归还超大 buffer,通过
    容量来断言,更可靠。
    Hical61 committed Jun 9, 2026
    Configuration menu
    Copy the full SHA
    c49619c View commit details
    Browse the repository at this point in the history
  3. [fix] MinGW thread_local析构时序导致进程退出堆损坏

    CI上msys2-gcc的6个测试在test body全过之后,进程退出时
    爆0xc0000374或SEGFAULT。追了大半圈发现是PoolSlots的
    ~PoolSlots()在DLL TLS回调里delete string,但那个回调
    跑的时候CRT堆已经不知道还在不在了。
    
    修复:PoolSlots析构用#ifndef __MINGW32__包起来,
    MinGW下不管了,进程退出OS会收。
    Hical61 committed Jun 9, 2026
    Configuration menu
    Copy the full SHA
    f353a67 View commit details
    Browse the repository at this point in the history

Commits on Jun 12, 2026

  1. [refactor] setBody 拆成单参/双参,热路径查表优化

    - setBody(string) 不再自动覆写 Content-Type,双参版才传
      所有内置错误响应(404/403/413/416/500/503)加回 text/plain
    - HeaderMap::toLower 和 Router::urlDecode 的 hex 转义改为
      编译期 256 查表(constexpr array),省掉运行时分支
    - HttpSessionImpl 扫 header 时顺手抓 Connection 值,
      不用再单独 O(n) find
    - OpenApiDocument::generateString() 改为按值返回,
      不暴露内部缓存引用,消除线程安全隐患
    - /docs 页面加了 Cache-Control: public, max-age=3600
    - 文档 api_reference.md 同步更新,移除 CLAUDE.md 里的版本号
    Hical61 committed Jun 12, 2026
    Configuration menu
    Copy the full SHA
    9f3802b View commit details
    Browse the repository at this point in the history
  2. [fix] AsyncFileSink 析构 data race + bump v2.6.5

    bgThread_ 声明在 flushRequests_ 之前,C++ 反向析构时
    flushRequests_ 先被销毁,后台线程可能还在并发访问它。
    
    把 bgThread_ 移到 flushRequests_ 后面作为最后声明的成员,
    保证先 stop+join 后台线程再销毁队列。TSan 确认不再报警。
    Hical61 committed Jun 12, 2026
    Configuration menu
    Copy the full SHA
    511fd19 View commit details
    Browse the repository at this point in the history
Loading