diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-07-30 14:28:58 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-08-12 20:23:07 -0700 |
commit | c5b21c3f4c17b0649155035d2f9aa97b2da8a813 (patch) | |
tree | c6d3a68b503ba5b16182acbb958e3e5dbc95a43b /libgo/go/context | |
parent | 72be20e20299ec57b4bc9ba03d5b7d6bf10e97cc (diff) | |
download | gcc-c5b21c3f4c17b0649155035d2f9aa97b2da8a813.zip gcc-c5b21c3f4c17b0649155035d2f9aa97b2da8a813.tar.gz gcc-c5b21c3f4c17b0649155035d2f9aa97b2da8a813.tar.bz2 |
libgo: update to Go1.17rc2
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/341629
Diffstat (limited to 'libgo/go/context')
-rw-r--r-- | libgo/go/context/benchmark_test.go | 14 | ||||
-rw-r--r-- | libgo/go/context/context.go | 30 | ||||
-rw-r--r-- | libgo/go/context/context_test.go | 6 |
3 files changed, 34 insertions, 16 deletions
diff --git a/libgo/go/context/benchmark_test.go b/libgo/go/context/benchmark_test.go index 5d56863..69d75ff 100644 --- a/libgo/go/context/benchmark_test.go +++ b/libgo/go/context/benchmark_test.go @@ -138,3 +138,17 @@ func BenchmarkCheckCanceled(b *testing.B) { } }) } + +func BenchmarkContextCancelDone(b *testing.B) { + ctx, cancel := WithCancel(Background()) + defer cancel() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + select { + case <-ctx.Done(): + default: + } + } + }) +} diff --git a/libgo/go/context/context.go b/libgo/go/context/context.go index b3fdb82..733c5f5 100644 --- a/libgo/go/context/context.go +++ b/libgo/go/context/context.go @@ -303,10 +303,8 @@ func parentCancelCtx(parent Context) (*cancelCtx, bool) { if !ok { return nil, false } - p.mu.Lock() - ok = p.done == done - p.mu.Unlock() - if !ok { + pdone, _ := p.done.Load().(chan struct{}) + if pdone != done { return nil, false } return p, true @@ -345,7 +343,7 @@ type cancelCtx struct { Context mu sync.Mutex // protects following fields - done chan struct{} // created lazily, closed by first cancel call + 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 } @@ -358,13 +356,18 @@ func (c *cancelCtx) Value(key interface{}) interface{} { } func (c *cancelCtx) Done() <-chan struct{} { + d := c.done.Load() + if d != nil { + return d.(chan struct{}) + } c.mu.Lock() - if c.done == nil { - c.done = make(chan struct{}) + defer c.mu.Unlock() + d = c.done.Load() + if d == nil { + d = make(chan struct{}) + c.done.Store(d) } - d := c.done - c.mu.Unlock() - return d + return d.(chan struct{}) } func (c *cancelCtx) Err() error { @@ -401,10 +404,11 @@ func (c *cancelCtx) cancel(removeFromParent bool, err error) { return // already canceled } c.err = err - if c.done == nil { - c.done = closedchan + d, _ := c.done.Load().(chan struct{}) + if d == nil { + c.done.Store(closedchan) } else { - close(c.done) + close(d) } for child := range c.children { // NOTE: acquiring the child's lock while holding parent's lock. diff --git a/libgo/go/context/context_test.go b/libgo/go/context/context_test.go index 6b392a2..a2e2324 100644 --- a/libgo/go/context/context_test.go +++ b/libgo/go/context/context_test.go @@ -525,7 +525,7 @@ func XTestInterlockedCancels(t testingT) { parent, cancelParent := WithCancel(Background()) child, cancelChild := WithCancel(parent) go func() { - parent.Done() + <-parent.Done() cancelChild() }() cancelParent() @@ -661,7 +661,7 @@ func XTestWithCancelCanceledParent(t testingT) { t.Errorf("child not done immediately upon construction") } if got, want := c.Err(), Canceled; got != want { - t.Errorf("child not cancelled; got = %v, want = %v", got, want) + t.Errorf("child not canceled; got = %v, want = %v", got, want) } } @@ -779,7 +779,7 @@ func XTestCustomContextGoroutines(t testingT) { defer cancel6() checkNoGoroutine() - // Check applied to cancelled context. + // Check applied to canceled context. cancel6() cancel1() _, cancel7 := WithCancel(ctx5) |