mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 09:28:14 +00:00
预存缺陷(非本次重构引入,但会稳定复现崩溃): Stop() 只 close 了 stop channel,而 Run() 阻塞在 evtfd.Read 里, 根本没有机会检查 stop。调用方在 Stop 后释放 ringData(host.Close 会 munmap 整个区域),Run 一旦从 Read 恢复就会读已解除映射的内存: **SIGSEGV,recover 捕不到**。实测 TestEventRing_OverflowStillDelivers 约 50% 概率触发。 两次尝试与结论: 1. os.File.SetReadDeadline 无效——eventfd/pipe 经 os.NewFile 包装后 **不会**注册进 Go netpoller(os.NewFile 对非 open 得到的 fd 一律按 非 pollable 处理),Read 是阻塞 syscall,SetReadDeadline 返回错误。 2. 改为 poll(2) 显式加超时(evtpoll_unix.go),消费循环每 100ms 回到 stop 检查。 新增 API 契约: - Stop() 非阻塞,仅请求退出 - Wait() 阻塞至 Run 退出;**返回后才能释放 ringData** - drainEvents 每条事件后检查 stop,避免慢 handler 拖延退出 其他: - evtring_test.go 三个用例改为 defer Wait() → defer Stop()(LIFO 保证 Wait 先于 host.Close 完成) - 溢出用例的 handler 改为非阻塞投递:写入了 8292 条事件而 channel 只 消费 1 条,阻塞投递会让 drainEvents 卡在 handler 里,Stop 无法退出