1
0
mirror of https://github.com/golang/go synced 2024-11-21 21:24:45 -07:00

context: use atomic.Pointer replace atomic.Value

Change-Id: I2ef89dc066c23f0599db3e0104ea44bbdb3858e5
This commit is contained in:
qiulaidongfeng 2024-08-29 10:44:41 +08:00
parent 9e8ea567c8
commit 6acb9f1a47

View File

@ -421,11 +421,11 @@ func init() {
type cancelCtx struct { type cancelCtx struct {
Context Context
mu sync.Mutex // protects following fields mu sync.Mutex // protects following fields
done atomic.Value // of chan struct{}, created lazily, closed by first cancel call done atomic.Pointer[chan struct{}] // created lazily, closed by first cancel call
children map[canceler]struct{} // set to nil by the 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 err error // set to non-nil by the first cancel call
cause 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 { func (c *cancelCtx) Value(key any) any {
@ -438,16 +438,14 @@ func (c *cancelCtx) Value(key any) any {
func (c *cancelCtx) Done() <-chan struct{} { func (c *cancelCtx) Done() <-chan struct{} {
d := c.done.Load() d := c.done.Load()
if d != nil { if d != nil {
return d.(chan struct{}) return *d
} }
c.mu.Lock() new := make(chan struct{})
defer c.mu.Unlock() if c.done.CompareAndSwap(nil, &new) {
d = c.done.Load() return new
if d == nil {
d = make(chan struct{})
c.done.Store(d)
} }
return d.(chan struct{}) return *c.done.Load()
} }
func (c *cancelCtx) Err() error { func (c *cancelCtx) Err() error {
@ -547,11 +545,11 @@ func (c *cancelCtx) cancel(removeFromParent bool, err, cause error) {
} }
c.err = err c.err = err
c.cause = cause c.cause = cause
d, _ := c.done.Load().(chan struct{}) d := c.done.Load()
if d == nil { if *d == nil {
c.done.Store(closedchan) c.done.Store(&closedchan)
} else { } else {
close(d) close(*d)
} }
for child := range c.children { for child := range c.children {
// NOTE: acquiring the child's lock while holding parent's lock. // NOTE: acquiring the child's lock while holding parent's lock.