Source file src/runtime/testdata/testgoroutineleakprofile/goker/grpc1460.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
     7   * Issue or PR  : https://github.com/grpc/grpc-go/pull/1460
     8   * Buggy version: 7db1564ba1229bc42919bb1f6d9c4186f3aa8678
     9   * fix commit-id: e605a1ecf24b634f94f4eefdab10a9ada98b70dd
    10   * Flaky: 100/100
    11   */
    12  package main
    13  
    14  import (
    15  	"os"
    16  	"runtime"
    17  	"runtime/pprof"
    18  	"sync"
    19  	"time"
    20  )
    21  
    22  func init() {
    23  	register("Grpc1460", Grpc1460)
    24  }
    25  
    26  type Stream_grpc1460 struct{}
    27  
    28  type http2Client_grpc1460 struct {
    29  	mu              sync.Mutex
    30  	awakenKeepalive chan struct{}
    31  	activeStream    []*Stream_grpc1460
    32  }
    33  
    34  func (t *http2Client_grpc1460) keepalive() {
    35  	t.mu.Lock()
    36  	if len(t.activeStream) < 1 {
    37  		<-t.awakenKeepalive
    38  		runtime.Gosched()
    39  		t.mu.Unlock()
    40  	} else {
    41  		t.mu.Unlock()
    42  	}
    43  }
    44  
    45  func (t *http2Client_grpc1460) NewStream() {
    46  	t.mu.Lock()
    47  	runtime.Gosched()
    48  	t.activeStream = append(t.activeStream, &Stream_grpc1460{})
    49  	if len(t.activeStream) == 1 {
    50  		select {
    51  		case t.awakenKeepalive <- struct{}{}:
    52  		default:
    53  		}
    54  	}
    55  	t.mu.Unlock()
    56  }
    57  
    58  ///
    59  /// G1 						G2
    60  /// client.keepalive()
    61  /// 						client.NewStream()
    62  /// t.mu.Lock()
    63  /// <-t.awakenKeepalive
    64  /// 						t.mu.Lock()
    65  /// ---------------G1, G2 deadlock--------------
    66  ///
    67  
    68  func Grpc1460() {
    69  	prof := pprof.Lookup("goroutineleak")
    70  	defer func() {
    71  		time.Sleep(100 * time.Millisecond)
    72  		prof.WriteTo(os.Stdout, 2)
    73  	}()
    74  
    75  	for i := 0; i < 1000; i++ {
    76  		go func() {
    77  			client := &http2Client_grpc1460{
    78  				awakenKeepalive: make(chan struct{}),
    79  			}
    80  			go client.keepalive() //G1
    81  			go client.NewStream() //G2
    82  		}()
    83  	}
    84  }
    85  

View as plain text