| // Copyright 2025 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a MIT | |
| // license that can be found in the LICENSE file. | |
| /* | |
| * Project: grpc-go | |
| * Issue or PR : https://github.com/grpc/grpc-go/pull/862 | |
| * Buggy version: d8f4ebe77f6b7b6403d7f98626de8a534f9b93a7 | |
| * fix commit-id: dd5645bebff44f6b88780bb949022a09eadd7dae | |
| * Flaky: 100/100 | |
| */ | |
| package main | |
| import ( | |
| "context" | |
| "os" | |
| "runtime" | |
| "runtime/pprof" | |
| "time" | |
| ) | |
| func init() { | |
| register("Grpc862", Grpc862) | |
| } | |
| type ClientConn_grpc862 struct { | |
| ctx context.Context | |
| cancel context.CancelFunc | |
| conns []*addrConn_grpc862 | |
| } | |
| func (cc *ClientConn_grpc862) Close() { | |
| cc.cancel() | |
| conns := cc.conns | |
| cc.conns = nil | |
| for _, ac := range conns { | |
| ac.tearDown() | |
| } | |
| } | |
| func (cc *ClientConn_grpc862) resetAddrConn() { | |
| ac := &addrConn_grpc862{ | |
| cc: cc, | |
| } | |
| cc.conns = append(cc.conns, ac) | |
| ac.ctx, ac.cancel = context.WithCancel(cc.ctx) | |
| ac.resetTransport() | |
| } | |
| type addrConn_grpc862 struct { | |
| cc *ClientConn_grpc862 | |
| ctx context.Context | |
| cancel context.CancelFunc | |
| } | |
| func (ac *addrConn_grpc862) resetTransport() { | |
| for retries := 1; ; retries++ { | |
| _ = 2 * time.Nanosecond * time.Duration(retries) | |
| timeout := 10 * time.Nanosecond | |
| _, cancel := context.WithTimeout(ac.ctx, timeout) | |
| _ = time.Now() | |
| cancel() | |
| <-ac.ctx.Done() | |
| return | |
| } | |
| } | |
| func (ac *addrConn_grpc862) tearDown() { | |
| ac.cancel() | |
| } | |
| func DialContext_grpc862(ctx context.Context) (conn *ClientConn_grpc862) { | |
| cc := &ClientConn_grpc862{} | |
| cc.ctx, cc.cancel = context.WithCancel(context.Background()) | |
| defer func() { | |
| select { | |
| case <-ctx.Done(): | |
| if conn != nil { | |
| conn.Close() | |
| } | |
| conn = nil | |
| default: | |
| } | |
| }() | |
| go func() { // G2 | |
| cc.resetAddrConn() | |
| }() | |
| return conn | |
| } | |
| func Grpc862() { | |
| prof := pprof.Lookup("goroutineleak") | |
| defer func() { | |
| // Yield several times to allow the child goroutine to run. | |
| for i := 0; i < yieldCount; i++ { | |
| runtime.Gosched() | |
| } | |
| prof.WriteTo(os.Stdout, 2) | |
| }() | |
| go func() { | |
| ctx, cancel := context.WithCancel(context.Background()) | |
| go DialContext_grpc862(ctx) // G1 | |
| go cancel() // helper goroutine | |
| }() | |
| } |