blob: 777534a788163c47c42183001ca82e3ed6d48349 [file] [log] [blame]
// 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/1424
* Buggy version: 39c8c3866d926d95e11c03508bf83d00f2963f91
* fix commit-id: 64bd0b04a7bb1982078bae6a2ab34c226125fbc1
* Flaky: 100/100
*/
package main
import (
"os"
"runtime/pprof"
"sync"
"time"
)
func init() {
register("Grpc1424", Grpc1424)
}
type Balancer_grpc1424 interface {
Notify() <-chan bool
}
type roundRobin_grpc1424 struct {
mu sync.Mutex
addrCh chan bool
}
func (rr *roundRobin_grpc1424) Notify() <-chan bool {
return rr.addrCh
}
type addrConn_grpc1424 struct {
mu sync.Mutex
}
func (ac *addrConn_grpc1424) tearDown() {
ac.mu.Lock()
defer ac.mu.Unlock()
}
type dialOption_grpc1424 struct {
balancer Balancer_grpc1424
}
type ClientConn_grpc1424 struct {
dopts dialOption_grpc1424
conns []*addrConn_grpc1424
}
func (cc *ClientConn_grpc1424) lbWatcher(doneChan chan bool) {
for addr := range cc.dopts.balancer.Notify() {
if addr {
// nop, make compiler happy
}
var (
del []*addrConn_grpc1424
)
for _, a := range cc.conns {
del = append(del, a)
}
for _, c := range del {
c.tearDown()
}
}
}
func NewClientConn_grpc1424() *ClientConn_grpc1424 {
cc := &ClientConn_grpc1424{
dopts: dialOption_grpc1424{
&roundRobin_grpc1424{addrCh: make(chan bool)},
},
}
return cc
}
func DialContext_grpc1424() {
cc := NewClientConn_grpc1424()
waitC := make(chan error, 1)
go func() { // G2
defer close(waitC)
ch := cc.dopts.balancer.Notify()
if ch != nil {
doneChan := make(chan bool)
go cc.lbWatcher(doneChan) // G3
<-doneChan
}
}()
/// close addrCh
close(cc.dopts.balancer.(*roundRobin_grpc1424).addrCh)
}
func Grpc1424() {
prof := pprof.Lookup("goroutineleak")
defer func() {
time.Sleep(100 * time.Millisecond)
prof.WriteTo(os.Stdout, 2)
}()
go DialContext_grpc1424() // G1
}