Source file src/runtime/testdata/testgoroutineleakprofile/goker/grpc862.go

     1  // Copyright 2025 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a MIT
     3  // license that can be found in the LICENSE file.
     4  
     5  /*
     6   * Project: grpc-go
     7   * Issue or PR   : https://github.com/grpc/grpc-go/pull/862
     8   * Buggy version: d8f4ebe77f6b7b6403d7f98626de8a534f9b93a7
     9   * fix commit-id: dd5645bebff44f6b88780bb949022a09eadd7dae
    10   * Flaky: 100/100
    11   */
    12  package main
    13  
    14  import (
    15  	"context"
    16  	"os"
    17  	"runtime"
    18  	"runtime/pprof"
    19  	"time"
    20  )
    21  
    22  func init() {
    23  	register("Grpc862", Grpc862)
    24  }
    25  
    26  type ClientConn_grpc862 struct {
    27  	ctx    context.Context
    28  	cancel context.CancelFunc
    29  	conns  []*addrConn_grpc862
    30  }
    31  
    32  func (cc *ClientConn_grpc862) Close() {
    33  	cc.cancel()
    34  	conns := cc.conns
    35  	cc.conns = nil
    36  	for _, ac := range conns {
    37  		ac.tearDown()
    38  	}
    39  }
    40  
    41  func (cc *ClientConn_grpc862) resetAddrConn() {
    42  	ac := &addrConn_grpc862{
    43  		cc: cc,
    44  	}
    45  	cc.conns = append(cc.conns, ac)
    46  	ac.ctx, ac.cancel = context.WithCancel(cc.ctx)
    47  	ac.resetTransport()
    48  }
    49  
    50  type addrConn_grpc862 struct {
    51  	cc     *ClientConn_grpc862
    52  	ctx    context.Context
    53  	cancel context.CancelFunc
    54  }
    55  
    56  func (ac *addrConn_grpc862) resetTransport() {
    57  	for retries := 1; ; retries++ {
    58  		_ = 2 * time.Nanosecond * time.Duration(retries)
    59  		timeout := 10 * time.Nanosecond
    60  		_, cancel := context.WithTimeout(ac.ctx, timeout)
    61  		_ = time.Now()
    62  		cancel()
    63  		<-ac.ctx.Done()
    64  		return
    65  	}
    66  }
    67  
    68  func (ac *addrConn_grpc862) tearDown() {
    69  	ac.cancel()
    70  }
    71  
    72  func DialContext_grpc862(ctx context.Context) (conn *ClientConn_grpc862) {
    73  	cc := &ClientConn_grpc862{}
    74  	cc.ctx, cc.cancel = context.WithCancel(context.Background())
    75  	defer func() {
    76  		select {
    77  		case <-ctx.Done():
    78  			if conn != nil {
    79  				conn.Close()
    80  			}
    81  			conn = nil
    82  		default:
    83  		}
    84  	}()
    85  	go func() { // G2
    86  		cc.resetAddrConn()
    87  	}()
    88  	return conn
    89  }
    90  
    91  func Grpc862() {
    92  	prof := pprof.Lookup("goroutineleak")
    93  	defer func() {
    94  		// Yield several times to allow the child goroutine to run.
    95  		for i := 0; i < yieldCount; i++ {
    96  			runtime.Gosched()
    97  		}
    98  		prof.WriteTo(os.Stdout, 2)
    99  	}()
   100  	go func() {
   101  		ctx, cancel := context.WithCancel(context.Background())
   102  		go DialContext_grpc862(ctx) // G1
   103  		go cancel()                 // helper goroutine
   104  	}()
   105  }
   106  

View as plain text