blob: 87cf157996800ec5ac6ec1ff19594691f3fcaa2c [file] [log] [blame]
// 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 (
"os"
"runtime/pprof"
"sync"
"sync/atomic"
"time"
)
func init() {
register("Cockroach1055", Cockroach1055)
}
type Stopper_cockroach1055 struct {
stopper chan struct{}
stop sync.WaitGroup
mu sync.Mutex
draining int32
drain sync.WaitGroup
}
func (s *Stopper_cockroach1055) AddWorker() {
s.stop.Add(1)
}
func (s *Stopper_cockroach1055) ShouldStop() <-chan struct{} {
if s == nil {
return nil
}
return s.stopper
}
func (s *Stopper_cockroach1055) SetStopped() {
if s != nil {
s.stop.Done()
}
}
func (s *Stopper_cockroach1055) Quiesce() {
s.mu.Lock()
defer s.mu.Unlock()
atomic.StoreInt32(&s.draining, 1)
s.drain.Wait()
atomic.StoreInt32(&s.draining, 0)
}
func (s *Stopper_cockroach1055) Stop() {
s.mu.Lock() // L1
defer s.mu.Unlock()
atomic.StoreInt32(&s.draining, 1)
s.drain.Wait()
close(s.stopper)
s.stop.Wait()
}
func (s *Stopper_cockroach1055) StartTask() bool {
if atomic.LoadInt32(&s.draining) == 0 {
s.mu.Lock()
defer s.mu.Unlock()
s.drain.Add(1)
return true
}
return false
}
func NewStopper_cockroach1055() *Stopper_cockroach1055 {
return &Stopper_cockroach1055{
stopper: make(chan struct{}),
}
}
func Cockroach1055() {
prof := pprof.Lookup("goroutineleak")
defer func() {
time.Sleep(100 * time.Millisecond)
prof.WriteTo(os.Stdout, 2)
}()
for i := 0; i <= 1000; i++ {
go func() { // G1
var stoppers []*Stopper_cockroach1055
for i := 0; i < 2; i++ {
stoppers = append(stoppers, NewStopper_cockroach1055())
}
for i := range stoppers {
s := stoppers[i]
s.AddWorker()
go func() { // G2
s.StartTask()
<-s.ShouldStop()
s.SetStopped()
}()
}
done := make(chan struct{})
go func() { // G3
for _, s := range stoppers {
s.Quiesce()
}
for _, s := range stoppers {
s.Stop()
}
close(done)
}()
<-done
}()
}
}