diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-05-31 21:42:53 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-05-31 21:42:53 +0000 |
commit | 11309337c4056975c0fbd83a8caee7663617bef2 (patch) | |
tree | 1d3b985ef7b1360b336c30a1d687a849a70ecc4a /libgo/go/net/lookup.go | |
parent | 8b0b334af3439179947522206b2478a28b908e61 (diff) |
libgo: update to Go 1.10.2 release
Reviewed-on: https://go-review.googlesource.com/115196
From-SVN: r261041
Diffstat (limited to 'libgo/go/net/lookup.go')
-rw-r--r-- | libgo/go/net/lookup.go | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go index 85e472932fc..a65b735f921 100644 --- a/libgo/go/net/lookup.go +++ b/libgo/go/net/lookup.go @@ -194,10 +194,16 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, err resolverFunc = alt } + // We don't want a cancelation of ctx to affect the + // lookupGroup operation. Otherwise if our context gets + // canceled it might cause an error to be returned to a lookup + // using a completely different context. + lookupGroupCtx, lookupGroupCancel := context.WithCancel(context.Background()) + dnsWaitGroup.Add(1) ch, called := lookupGroup.DoChan(host, func() (interface{}, error) { defer dnsWaitGroup.Done() - return testHookLookupIP(ctx, resolverFunc, host) + return testHookLookupIP(lookupGroupCtx, resolverFunc, host) }) if !called { dnsWaitGroup.Done() @@ -205,20 +211,28 @@ func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, err select { case <-ctx.Done(): - // If the DNS lookup timed out for some reason, force - // future requests to start the DNS lookup again - // rather than waiting for the current lookup to - // complete. See issue 8602. - ctxErr := ctx.Err() - if ctxErr == context.DeadlineExceeded { - lookupGroup.Forget(host) + // Our context was canceled. If we are the only + // goroutine looking up this key, then drop the key + // from the lookupGroup and cancel the lookup. + // If there are other goroutines looking up this key, + // let the lookup continue uncanceled, and let later + // lookups with the same key share the result. + // See issues 8602, 20703, 22724. + if lookupGroup.ForgetUnshared(host) { + lookupGroupCancel() + } else { + go func() { + <-ch + lookupGroupCancel() + }() } - err := mapErr(ctxErr) + err := mapErr(ctx.Err()) if trace != nil && trace.DNSDone != nil { trace.DNSDone(nil, false, err) } return nil, err case r := <-ch: + lookupGroupCancel() if trace != nil && trace.DNSDone != nil { addrs, _ := r.Val.([]IPAddr) trace.DNSDone(ipAddrsEface(addrs), r.Shared, r.Err) |