Source file src/runtime/testdata/testgoroutineleakprofile/goker/hugo3251.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  	"fmt"
     9  	"os"
    10  	"runtime"
    11  	"runtime/pprof"
    12  	"sync"
    13  	"time"
    14  )
    15  
    16  func init() {
    17  	register("Hugo3251", Hugo3251)
    18  }
    19  
    20  type remoteLock_hugo3251 struct {
    21  	sync.RWMutex                        // L1
    22  	m            map[string]*sync.Mutex // L2
    23  }
    24  
    25  func (l *remoteLock_hugo3251) URLLock(url string) {
    26  	l.Lock() // L1
    27  	if _, ok := l.m[url]; !ok {
    28  		l.m[url] = &sync.Mutex{}
    29  	}
    30  	l.m[url].Lock() // L2
    31  	runtime.Gosched()
    32  	l.Unlock() // L1
    33  	// runtime.Gosched()
    34  }
    35  
    36  func (l *remoteLock_hugo3251) URLUnlock(url string) {
    37  	l.RLock()         // L1
    38  	defer l.RUnlock() // L1
    39  	if um, ok := l.m[url]; ok {
    40  		um.Unlock() // L2
    41  	}
    42  }
    43  
    44  func resGetRemote_hugo3251(remoteURLLock *remoteLock_hugo3251, url string) error {
    45  	remoteURLLock.URLLock(url)
    46  	defer func() { remoteURLLock.URLUnlock(url) }()
    47  
    48  	return nil
    49  }
    50  
    51  func Hugo3251() {
    52  	prof := pprof.Lookup("goroutineleak")
    53  	defer func() {
    54  		time.Sleep(time.Second)
    55  		prof.WriteTo(os.Stdout, 2)
    56  	}()
    57  
    58  	for i := 0; i < 11; i++ {
    59  		go func() { // G1
    60  			url := "http://Foo.Bar/foo_Bar-Foo"
    61  			remoteURLLock := &remoteLock_hugo3251{m: make(map[string]*sync.Mutex)}
    62  			for range []bool{false, true} {
    63  				var wg sync.WaitGroup
    64  				for i := 0; i < 100; i++ {
    65  					wg.Add(1)
    66  					go func(gor int) { // G2
    67  						defer wg.Done()
    68  						for j := 0; j < 200; j++ {
    69  							err := resGetRemote_hugo3251(remoteURLLock, url)
    70  							if err != nil {
    71  								fmt.Errorf("Error getting resource content: %s", err)
    72  							}
    73  							time.Sleep(300 * time.Nanosecond)
    74  						}
    75  					}(i)
    76  				}
    77  				wg.Wait()
    78  			}
    79  		}()
    80  	}
    81  }

View as plain text