fix: orDone 使用 sync.Once 修复 close(done) 竞态条件

修复 Gemini 审查意见:多 goroutine 同时 close(done) 可能导致 panic。
恢复 sync.Once 保证 channel 只被关闭一次。

Alina Agent生成
This commit is contained in:
wjqserver 2026-04-22 09:37:19 +08:00
parent 2d693e3b13
commit 9dcab4b1ae

View file

@ -6,6 +6,7 @@ package touka
import ( import (
"context" "context"
"sync"
"time" "time"
) )
@ -120,15 +121,12 @@ func (mc *mergedContext) Value(key any) any {
// orDone 返回一个 channel, 当任意一个输入 context 的 Done() channel 关闭时关闭. // orDone 返回一个 channel, 当任意一个输入 context 的 Done() channel 关闭时关闭.
func orDone(contexts ...context.Context) <-chan struct{} { func orDone(contexts ...context.Context) <-chan struct{} {
done := make(chan struct{}) done := make(chan struct{})
var once sync.Once
for _, ctx := range contexts { for _, ctx := range contexts {
go func(c context.Context) { go func(c context.Context) {
select { select {
case <-c.Done(): case <-c.Done():
select { once.Do(func() { close(done) })
case <-done:
default:
close(done)
}
case <-done: case <-done:
} }
}(ctx) }(ctx)