From: Joe Wreschnig Date: Sat, 13 Jun 2020 15:41:23 +0000 (+0200) Subject: Reuse the same channel for all precompleted contexts X-Git-Url: https://git.korewanetadesu.com/?p=go-signalcontext.git;a=commitdiff_plain;h=6d43b73af18d23a4cab88dccf8d93a8eb423d2ed;hp=3ee8799a0bb3e7ba3628b83832fb14462241643d Reuse the same channel for all precompleted contexts This avoids making a new channel and immediately closing it. `benchcmp` says: benchmark old ns/op new ns/op delta BenchmarkPrecompleted-4 213 138 -35.21% benchmark old allocs new allocs delta BenchmarkPrecompleted-4 3 2 -33.33% benchmark old bytes new bytes delta BenchmarkPrecompleted-4 176 80 -54.55% --- diff --git a/context.go b/context.go index 1bd24d3..3681417 100644 --- a/context.go +++ b/context.go @@ -28,14 +28,14 @@ type Context struct { func UntilSignal(parent context.Context, sig ...os.Signal) *Context { ctx := new(Context) ctx.parent = parent - ctx.done = make(chan struct{}) if err := parent.Err(); err != nil { - close(ctx.done) + ctx.done = alreadyclosed ctx.err = err return ctx } + ctx.done = make(chan struct{}) ctx.c = make(chan os.Signal, 1) signal.Notify(ctx.c, sig...) go ctx.wait(sig...) @@ -103,3 +103,11 @@ func (s *Context) Err() error { s.m.Unlock() return err } + +// Reuse the same channel for all contexts which begin life already +// completed. +var alreadyclosed = make(chan struct{}) + +func init() { + close(alreadyclosed) +}