mirror of
https://github.com/golang/go
synced 2024-11-22 03:14:41 -07:00
context: use atomic.Pointer replace atomic.Value
Change-Id: I2ef89dc066c23f0599db3e0104ea44bbdb3858e5
This commit is contained in:
parent
9e8ea567c8
commit
6acb9f1a47
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user