Source file src/runtime/testdata/testgoroutineleakprofile/goker/istio18454.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  	"context"
     9  	"os"
    10  	"runtime/pprof"
    11  
    12  	"sync"
    13  	"time"
    14  )
    15  
    16  func init() {
    17  	register("Istio18454", Istio18454)
    18  }
    19  
    20  const eventChCap_istio18454 = 1024
    21  
    22  type Worker_istio18454 struct {
    23  	ctx       context.Context
    24  	ctxCancel context.CancelFunc
    25  }
    26  
    27  func (w *Worker_istio18454) Start(setupFn func(), runFn func(c context.Context)) {
    28  	if setupFn != nil {
    29  		setupFn()
    30  	}
    31  	go func() {
    32  		runFn(w.ctx)
    33  	}()
    34  }
    35  
    36  func (w *Worker_istio18454) Stop() {
    37  	w.ctxCancel()
    38  }
    39  
    40  type Strategy_istio18454 struct {
    41  	timer          *time.Timer
    42  	timerFrequency time.Duration
    43  	stateLock      sync.Mutex
    44  	resetChan      chan struct{}
    45  	worker         *Worker_istio18454
    46  	startTimerFn   func()
    47  }
    48  
    49  func (s *Strategy_istio18454) OnChange() {
    50  	s.stateLock.Lock()
    51  	if s.timer != nil {
    52  		s.stateLock.Unlock()
    53  		s.resetChan <- struct{}{}
    54  		return
    55  	}
    56  	s.startTimerFn()
    57  	s.stateLock.Unlock()
    58  }
    59  
    60  func (s *Strategy_istio18454) startTimer() {
    61  	s.timer = time.NewTimer(s.timerFrequency)
    62  	eventLoop := func(ctx context.Context) {
    63  		for {
    64  			select {
    65  			case <-s.timer.C:
    66  			case <-s.resetChan:
    67  				if !s.timer.Stop() {
    68  					<-s.timer.C
    69  				}
    70  				s.timer.Reset(s.timerFrequency)
    71  			case <-ctx.Done():
    72  				s.timer.Stop()
    73  				return
    74  			}
    75  		}
    76  	}
    77  	s.worker.Start(nil, eventLoop)
    78  }
    79  
    80  func (s *Strategy_istio18454) Close() {
    81  	s.worker.Stop()
    82  }
    83  
    84  type Event_istio18454 int
    85  
    86  type Processor_istio18454 struct {
    87  	stateStrategy *Strategy_istio18454
    88  	worker        *Worker_istio18454
    89  	eventCh       chan Event_istio18454
    90  }
    91  
    92  func (p *Processor_istio18454) processEvent() {
    93  	p.stateStrategy.OnChange()
    94  }
    95  
    96  func (p *Processor_istio18454) Start() {
    97  	setupFn := func() {
    98  		for i := 0; i < eventChCap_istio18454; i++ {
    99  			p.eventCh <- Event_istio18454(0)
   100  		}
   101  	}
   102  	runFn := func(ctx context.Context) {
   103  		defer func() {
   104  			p.stateStrategy.Close()
   105  		}()
   106  		for {
   107  			select {
   108  			case <-ctx.Done():
   109  				return
   110  			case <-p.eventCh:
   111  				p.processEvent()
   112  			}
   113  		}
   114  	}
   115  	p.worker.Start(setupFn, runFn)
   116  }
   117  
   118  func (p *Processor_istio18454) Stop() {
   119  	p.worker.Stop()
   120  }
   121  
   122  func NewWorker_istio18454() *Worker_istio18454 {
   123  	worker := &Worker_istio18454{}
   124  	worker.ctx, worker.ctxCancel = context.WithCancel(context.Background())
   125  	return worker
   126  }
   127  
   128  func Istio18454() {
   129  	prof := pprof.Lookup("goroutineleak")
   130  	defer func() {
   131  		time.Sleep(100 * time.Millisecond)
   132  		prof.WriteTo(os.Stdout, 2)
   133  	}()
   134  
   135  	for i := 0; i < 100; i++ {
   136  		go func() {
   137  			stateStrategy := &Strategy_istio18454{
   138  				timerFrequency: time.Nanosecond,
   139  				resetChan:      make(chan struct{}, 1),
   140  				worker:         NewWorker_istio18454(),
   141  			}
   142  			stateStrategy.startTimerFn = stateStrategy.startTimer
   143  
   144  			p := &Processor_istio18454{
   145  				stateStrategy: stateStrategy,
   146  				worker:        NewWorker_istio18454(),
   147  				eventCh:       make(chan Event_istio18454, eventChCap_istio18454),
   148  			}
   149  
   150  			p.Start()
   151  			defer p.Stop()
   152  		}()
   153  	}
   154  }
   155  

View as plain text