aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/context
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-07-30 14:28:58 -0700
committerIan Lance Taylor <iant@golang.org>2021-08-12 20:23:07 -0700
commitc5b21c3f4c17b0649155035d2f9aa97b2da8a813 (patch)
treec6d3a68b503ba5b16182acbb958e3e5dbc95a43b /libgo/go/context
parent72be20e20299ec57b4bc9ba03d5b7d6bf10e97cc (diff)
downloadgcc-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.go14
-rw-r--r--libgo/go/context/context.go30
-rw-r--r--libgo/go/context/context_test.go6
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)