From 9dcab4b1ae609a0ca33d8e5c803c34c42fe3a38d Mon Sep 17 00:00:00 2001 From: wjqserver <114663932+WJQSERVER@users.noreply.github.com> Date: Wed, 22 Apr 2026 09:37:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20orDone=20=E4=BD=BF=E7=94=A8=20sync.Once?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=20close(done)=20=E7=AB=9E=E6=80=81?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复 Gemini 审查意见:多 goroutine 同时 close(done) 可能导致 panic。 恢复 sync.Once 保证 channel 只被关闭一次。 Alina Agent生成 --- mergectx.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mergectx.go b/mergectx.go index 9c30b92..404f7b1 100644 --- a/mergectx.go +++ b/mergectx.go @@ -6,6 +6,7 @@ package touka import ( "context" + "sync" "time" ) @@ -120,15 +121,12 @@ func (mc *mergedContext) Value(key any) any { // orDone 返回一个 channel, 当任意一个输入 context 的 Done() channel 关闭时关闭. func orDone(contexts ...context.Context) <-chan struct{} { done := make(chan struct{}) + var once sync.Once for _, ctx := range contexts { go func(c context.Context) { select { case <-c.Done(): - select { - case <-done: - default: - close(done) - } + once.Do(func() { close(done) }) case <-done: } }(ctx)