Source file src/runtime/testdata/testgoroutineleakprofile/goker/syncthing4829.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  )
    13  
    14  func init() {
    15  	register("Syncthing4829", Syncthing4829)
    16  }
    17  
    18  type Address_syncthing4829 int
    19  
    20  type Mapping_syncthing4829 struct {
    21  	mut sync.RWMutex // L2
    22  
    23  	extAddresses map[string]Address_syncthing4829
    24  }
    25  
    26  func (m *Mapping_syncthing4829) clearAddresses() {
    27  	m.mut.Lock() // L2
    28  	var removed []Address_syncthing4829
    29  	for id, addr := range m.extAddresses {
    30  		removed = append(removed, addr)
    31  		delete(m.extAddresses, id)
    32  	}
    33  	if len(removed) > 0 {
    34  		m.notify(nil, removed)
    35  	}
    36  	m.mut.Unlock() // L2
    37  }
    38  
    39  func (m *Mapping_syncthing4829) notify(added, remove []Address_syncthing4829) {
    40  	m.mut.RLock() // L2
    41  	m.mut.RUnlock() // L2
    42  }
    43  
    44  type Service_syncthing4829 struct {
    45  	mut sync.RWMutex // L1
    46  
    47  	mappings []*Mapping_syncthing4829
    48  }
    49  
    50  func (s *Service_syncthing4829) NewMapping() *Mapping_syncthing4829 {
    51  	mapping := &Mapping_syncthing4829{
    52  		extAddresses: make(map[string]Address_syncthing4829),
    53  	}
    54  	s.mut.Lock() // L1
    55  	s.mappings = append(s.mappings, mapping)
    56  	s.mut.Unlock() // L1
    57  	return mapping
    58  }
    59  
    60  func (s *Service_syncthing4829) RemoveMapping(mapping *Mapping_syncthing4829) {
    61  	s.mut.Lock() // L1
    62  	defer s.mut.Unlock() // L1
    63  	for _, existing := range s.mappings {
    64  		if existing == mapping {
    65  			mapping.clearAddresses()
    66  		}
    67  	}
    68  }
    69  
    70  func Syncthing4829() {
    71  	prof := pprof.Lookup("goroutineleak")
    72  	defer func() {
    73  		// Yield several times to allow the child goroutine to run.
    74  		for i := 0; i < yieldCount; i++ {
    75  			runtime.Gosched()
    76  		}
    77  		prof.WriteTo(os.Stdout, 2)
    78  	}()
    79  
    80  	go func() { // G1
    81  		natSvc := &Service_syncthing4829{}
    82  		m := natSvc.NewMapping()
    83  		m.extAddresses["test"] = 0
    84  
    85  		natSvc.RemoveMapping(m)
    86  	}()
    87  }
    88  

View as plain text