Source file src/runtime/testdata/testgoroutineleakprofile/goker/cockroach1055.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/pprof"
    10  	"sync"
    11  	"sync/atomic"
    12  	"time"
    13  )
    14  
    15  func init() {
    16  	register("Cockroach1055", Cockroach1055)
    17  }
    18  
    19  type Stopper_cockroach1055 struct {
    20  	stopper  chan struct{}
    21  	stop     sync.WaitGroup
    22  	mu       sync.Mutex
    23  	draining int32
    24  	drain    sync.WaitGroup
    25  }
    26  
    27  func (s *Stopper_cockroach1055) AddWorker() {
    28  	s.stop.Add(1)
    29  }
    30  
    31  func (s *Stopper_cockroach1055) ShouldStop() <-chan struct{} {
    32  	if s == nil {
    33  		return nil
    34  	}
    35  	return s.stopper
    36  }
    37  
    38  func (s *Stopper_cockroach1055) SetStopped() {
    39  	if s != nil {
    40  		s.stop.Done()
    41  	}
    42  }
    43  
    44  func (s *Stopper_cockroach1055) Quiesce() {
    45  	s.mu.Lock()
    46  	defer s.mu.Unlock()
    47  	atomic.StoreInt32(&s.draining, 1)
    48  	s.drain.Wait()
    49  	atomic.StoreInt32(&s.draining, 0)
    50  }
    51  
    52  func (s *Stopper_cockroach1055) Stop() {
    53  	s.mu.Lock() // L1
    54  	defer s.mu.Unlock()
    55  	atomic.StoreInt32(&s.draining, 1)
    56  	s.drain.Wait()
    57  	close(s.stopper)
    58  	s.stop.Wait()
    59  }
    60  
    61  func (s *Stopper_cockroach1055) StartTask() bool {
    62  	if atomic.LoadInt32(&s.draining) == 0 {
    63  		s.mu.Lock()
    64  		defer s.mu.Unlock()
    65  		s.drain.Add(1)
    66  		return true
    67  	}
    68  	return false
    69  }
    70  
    71  func NewStopper_cockroach1055() *Stopper_cockroach1055 {
    72  	return &Stopper_cockroach1055{
    73  		stopper: make(chan struct{}),
    74  	}
    75  }
    76  
    77  func Cockroach1055() {
    78  	prof := pprof.Lookup("goroutineleak")
    79  	defer func() {
    80  		time.Sleep(100 * time.Millisecond)
    81  		prof.WriteTo(os.Stdout, 2)
    82  	}()
    83  
    84  	for i := 0; i <= 1000; i++ {
    85  		go func() { // G1
    86  			var stoppers []*Stopper_cockroach1055
    87  			for i := 0; i < 2; i++ {
    88  				stoppers = append(stoppers, NewStopper_cockroach1055())
    89  			}
    90  
    91  			for i := range stoppers {
    92  				s := stoppers[i]
    93  				s.AddWorker()
    94  				go func() { // G2
    95  					s.StartTask()
    96  					<-s.ShouldStop()
    97  					s.SetStopped()
    98  				}()
    99  			}
   100  
   101  			done := make(chan struct{})
   102  			go func() { // G3
   103  				for _, s := range stoppers {
   104  					s.Quiesce()
   105  				}
   106  				for _, s := range stoppers {
   107  					s.Stop()
   108  				}
   109  				close(done)
   110  			}()
   111  
   112  			<-done
   113  		}()
   114  	}
   115  }
   116  

View as plain text