From 6acb9f1a47d771a9f7c693e0de80f7fdbebf812f Mon Sep 17 00:00:00 2001 From: qiulaidongfeng <2645477756@qq.com> Date: Thu, 29 Aug 2024 10:44:41 +0800 Subject: [PATCH] context: use atomic.Pointer replace atomic.Value Change-Id: I2ef89dc066c23f0599db3e0104ea44bbdb3858e5 --- src/context/context.go | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/context/context.go b/src/context/context.go index 763d4f777ff..fa679e4df2b 100644 --- a/src/context/context.go +++ b/src/context/context.go @@ -421,11 +421,11 @@ func init() { type cancelCtx struct { Context - mu sync.Mutex // protects following fields - done atomic.Value // of chan struct{}, created lazily, closed by first cancel call - children map[canceler]struct{} // set to nil by the first cancel call - err error // set to non-nil by the first cancel call - cause error // set to non-nil by the first cancel call + mu sync.Mutex // protects following fields + done atomic.Pointer[chan struct{}] // created lazily, closed by first cancel call + children map[canceler]struct{} // set to nil by the first cancel call + err error // set to non-nil by the first cancel call + cause error // set to non-nil by the first cancel call } func (c *cancelCtx) Value(key any) any { @@ -438,16 +438,14 @@ func (c *cancelCtx) Value(key any) any { func (c *cancelCtx) Done() <-chan struct{} { d := c.done.Load() if d != nil { - return d.(chan struct{}) + return *d } - c.mu.Lock() - defer c.mu.Unlock() - d = c.done.Load() - if d == nil { - d = make(chan struct{}) - c.done.Store(d) + new := make(chan struct{}) + if c.done.CompareAndSwap(nil, &new) { + return new } - return d.(chan struct{}) + return *c.done.Load() + } func (c *cancelCtx) Err() error { @@ -547,11 +545,11 @@ func (c *cancelCtx) cancel(removeFromParent bool, err, cause error) { } c.err = err c.cause = cause - d, _ := c.done.Load().(chan struct{}) - if d == nil { - c.done.Store(closedchan) + d := c.done.Load() + if *d == nil { + c.done.Store(&closedchan) } else { - close(d) + close(*d) } for child := range c.children { // NOTE: acquiring the child's lock while holding parent's lock.