// 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. package main import ( "context" "os" "runtime/pprof" "sync" "time" ) func init() { register("Istio17860", Istio17860) } type Proxy_istio17860 interface { IsLive() bool } type TestProxy_istio17860 struct { live func() bool } func (tp TestProxy_istio17860) IsLive() bool { if tp.live == nil { return true } return tp.live() } type Agent_istio17860 interface { Run(ctx context.Context) Restart() } type exitStatus_istio17860 int type agent_istio17860 struct { proxy Proxy_istio17860 mu *sync.Mutex statusCh chan exitStatus_istio17860 currentEpoch int activeEpochs map[int]struct{} } func (a *agent_istio17860) Run(ctx context.Context) { for { select { case status := <-a.statusCh: a.mu.Lock() delete(a.activeEpochs, int(status)) active := len(a.activeEpochs) a.mu.Unlock() if active == 0 { return } case <-ctx.Done(): return } } } func (a *agent_istio17860) Restart() { a.mu.Lock() defer a.mu.Unlock() a.waitUntilLive() a.currentEpoch++ a.activeEpochs[a.currentEpoch] = struct{}{} go a.runWait(a.currentEpoch) } func (a *agent_istio17860) runWait(epoch int) { a.statusCh <- exitStatus_istio17860(epoch) } func (a *agent_istio17860) waitUntilLive() { if len(a.activeEpochs) == 0 { return } interval := time.NewTicker(30 * time.Nanosecond) timer := time.NewTimer(100 * time.Nanosecond) defer func() { interval.Stop() timer.Stop() }() if a.proxy.IsLive() { return } for { select { case <-timer.C: return case <-interval.C: if a.proxy.IsLive() { return } } } } func NewAgent_istio17860(proxy Proxy_istio17860) Agent_istio17860 { return &agent_istio17860{ proxy: proxy, mu: &sync.Mutex{}, statusCh: make(chan exitStatus_istio17860), activeEpochs: make(map[int]struct{}), } } func Istio17860() { prof := pprof.Lookup("goroutineleak") defer func() { time.Sleep(100 * time.Millisecond) prof.WriteTo(os.Stdout, 2) }() for i := 0; i < 100; i++ { go func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() neverLive := func() bool { return false } a := NewAgent_istio17860(TestProxy_istio17860{live: neverLive}) go func() { a.Run(ctx) }() a.Restart() go a.Restart() time.Sleep(200 * time.Nanosecond) }() } }