Source file src/runtime/testdata/testgoroutineleakprofile/goker/cockroach1462.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  package main
     6  
     7  import (
     8  	"os"
     9  	"runtime"
    10  	"runtime/pprof"
    11  	"sync"
    12  	"time"
    13  )
    14  
    15  func init() {
    16  	register("Cockroach1462", Cockroach1462)
    17  }
    18  
    19  type Stopper_cockroach1462 struct {
    20  	stopper  chan struct{}
    21  	stopped  chan struct{}
    22  	stop     sync.WaitGroup
    23  	mu       sync.Mutex
    24  	drain    *sync.Cond
    25  	draining bool
    26  	numTasks int
    27  }
    28  
    29  func NewStopper_cockroach1462() *Stopper_cockroach1462 {
    30  	s := &Stopper_cockroach1462{
    31  		stopper: make(chan struct{}),
    32  		stopped: make(chan struct{}),
    33  	}
    34  	s.drain = sync.NewCond(&s.mu)
    35  	return s
    36  }
    37  
    38  func (s *Stopper_cockroach1462) RunWorker(f func()) {
    39  	s.AddWorker()
    40  	go func() { // G2, G3
    41  		defer s.SetStopped()
    42  		f()
    43  	}()
    44  }
    45  
    46  func (s *Stopper_cockroach1462) AddWorker() {
    47  	s.stop.Add(1)
    48  }
    49  func (s *Stopper_cockroach1462) StartTask() bool {
    50  	s.mu.Lock()
    51  	runtime.Gosched()
    52  	defer s.mu.Unlock()
    53  	if s.draining {
    54  		return false
    55  	}
    56  	s.numTasks++
    57  	return true
    58  }
    59  
    60  func (s *Stopper_cockroach1462) FinishTask() {
    61  	s.mu.Lock()
    62  	runtime.Gosched()
    63  	defer s.mu.Unlock()
    64  	s.numTasks--
    65  	s.drain.Broadcast()
    66  }
    67  func (s *Stopper_cockroach1462) SetStopped() {
    68  	if s != nil {
    69  		s.stop.Done()
    70  	}
    71  }
    72  func (s *Stopper_cockroach1462) ShouldStop() <-chan struct{} {
    73  	if s == nil {
    74  		return nil
    75  	}
    76  	return s.stopper
    77  }
    78  
    79  func (s *Stopper_cockroach1462) Quiesce() {
    80  	s.mu.Lock()
    81  	runtime.Gosched()
    82  	defer s.mu.Unlock()
    83  	s.draining = true
    84  	for s.numTasks > 0 {
    85  		// Unlock s.mu, wait for the signal, and lock s.mu.
    86  		s.drain.Wait()
    87  	}
    88  }
    89  
    90  func (s *Stopper_cockroach1462) Stop() {
    91  	s.Quiesce()
    92  	close(s.stopper)
    93  	s.stop.Wait()
    94  	s.mu.Lock()
    95  	runtime.Gosched()
    96  	defer s.mu.Unlock()
    97  	close(s.stopped)
    98  }
    99  
   100  type interceptMessage_cockroach1462 int
   101  
   102  type localInterceptableTransport_cockroach1462 struct {
   103  	mu      sync.Mutex
   104  	Events  chan interceptMessage_cockroach1462
   105  	stopper *Stopper_cockroach1462
   106  }
   107  
   108  func (lt *localInterceptableTransport_cockroach1462) Close() {}
   109  
   110  type Transport_cockroach1462 interface {
   111  	Close()
   112  }
   113  
   114  func NewLocalInterceptableTransport_cockroach1462(stopper *Stopper_cockroach1462) Transport_cockroach1462 {
   115  	lt := &localInterceptableTransport_cockroach1462{
   116  		Events:  make(chan interceptMessage_cockroach1462),
   117  		stopper: stopper,
   118  	}
   119  	lt.start()
   120  	return lt
   121  }
   122  
   123  func (lt *localInterceptableTransport_cockroach1462) start() {
   124  	lt.stopper.RunWorker(func() {
   125  		for {
   126  			select {
   127  			case <-lt.stopper.ShouldStop():
   128  				return
   129  			default:
   130  				lt.Events <- interceptMessage_cockroach1462(0)
   131  			}
   132  		}
   133  	})
   134  }
   135  
   136  func processEventsUntil_cockroach1462(ch <-chan interceptMessage_cockroach1462, stopper *Stopper_cockroach1462) {
   137  	for {
   138  		select {
   139  		case _, ok := <-ch:
   140  			runtime.Gosched()
   141  			if !ok {
   142  				return
   143  			}
   144  		case <-stopper.ShouldStop():
   145  			return
   146  		}
   147  	}
   148  }
   149  
   150  func Cockroach1462() {
   151  	prof := pprof.Lookup("goroutineleak")
   152  	defer func() {
   153  		time.Sleep(2000 * time.Millisecond)
   154  		prof.WriteTo(os.Stdout, 2)
   155  	}()
   156  	for i := 0; i <= 1000; i++ {
   157  		go func() { // G1
   158  			stopper := NewStopper_cockroach1462()
   159  			transport := NewLocalInterceptableTransport_cockroach1462(stopper).(*localInterceptableTransport_cockroach1462)
   160  			stopper.RunWorker(func() {
   161  				processEventsUntil_cockroach1462(transport.Events, stopper)
   162  			})
   163  			stopper.Stop()
   164  		}()
   165  	}
   166  }
   167  
   168  

View as plain text