Source file src/runtime/testdata/testgoroutineleakprofile/goker/hugo5379.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  	"log"
    10  	"os"
    11  	"runtime/pprof"
    12  	"sync"
    13  	"time"
    14  )
    15  
    16  func init() {
    17  	register("Hugo5379", Hugo5379)
    18  }
    19  
    20  type shortcodeHandler_hugo5379 struct {
    21  	p                      *PageWithoutContent_hugo5379
    22  	contentShortcodes      map[int]func() error
    23  	contentShortcodesDelta map[int]func() error
    24  	init                   sync.Once // O1
    25  }
    26  
    27  func (s *shortcodeHandler_hugo5379) executeShortcodesForDelta(p *PageWithoutContent_hugo5379) error {
    28  	for k, _ := range s.contentShortcodesDelta {
    29  		render := s.contentShortcodesDelta[k]
    30  		if err := render(); err != nil {
    31  			continue
    32  		}
    33  	}
    34  	return nil
    35  }
    36  
    37  func (s *shortcodeHandler_hugo5379) updateDelta() {
    38  	s.init.Do(func() {
    39  		s.contentShortcodes = createShortcodeRenderers_hugo5379(s.p.withoutContent())
    40  	})
    41  
    42  	delta := make(map[int]func() error)
    43  
    44  	for k, v := range s.contentShortcodes {
    45  		if _, ok := delta[k]; !ok {
    46  			delta[k] = v
    47  		}
    48  	}
    49  
    50  	s.contentShortcodesDelta = delta
    51  }
    52  
    53  type Page_hugo5379 struct {
    54  	*pageInit_hugo5379
    55  	*pageContentInit_hugo5379
    56  	pageWithoutContent *PageWithoutContent_hugo5379
    57  	contentInit        sync.Once  // O2
    58  	contentInitMu      sync.Mutex // L1
    59  	shortcodeState     *shortcodeHandler_hugo5379
    60  }
    61  
    62  func (p *Page_hugo5379) WordCount() {
    63  	p.initContentPlainAndMeta()
    64  }
    65  
    66  func (p *Page_hugo5379) initContentPlainAndMeta() {
    67  	p.initContent()
    68  	p.initPlain(true)
    69  }
    70  
    71  func (p *Page_hugo5379) initPlain(lock bool) {
    72  	p.plainInit.Do(func() {
    73  		if lock {
    74  			/// Double locking here.
    75  			p.contentInitMu.Lock()
    76  			defer p.contentInitMu.Unlock()
    77  		}
    78  	})
    79  }
    80  
    81  func (p *Page_hugo5379) withoutContent() *PageWithoutContent_hugo5379 {
    82  	p.pageInit_hugo5379.withoutContentInit.Do(func() {
    83  		p.pageWithoutContent = &PageWithoutContent_hugo5379{Page_hugo5379: p}
    84  	})
    85  	return p.pageWithoutContent
    86  }
    87  
    88  func (p *Page_hugo5379) prepareForRender() error {
    89  	var err error
    90  	if err = handleShortcodes_hugo5379(p.withoutContent()); err != nil {
    91  		return err
    92  	}
    93  	return nil
    94  }
    95  
    96  func (p *Page_hugo5379) setContentInit() {
    97  	p.shortcodeState.updateDelta()
    98  }
    99  
   100  func (p *Page_hugo5379) initContent() {
   101  	p.contentInit.Do(func() {
   102  		ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
   103  		defer cancel()
   104  		c := make(chan error, 1)
   105  
   106  		go func() { // G2
   107  			var err error
   108  			p.contentInitMu.Lock() // first lock here
   109  			defer p.contentInitMu.Unlock()
   110  
   111  			err = p.prepareForRender()
   112  			if err != nil {
   113  				c <- err
   114  				return
   115  			}
   116  			c <- err
   117  		}()
   118  
   119  		select {
   120  		case <-ctx.Done():
   121  		case <-c:
   122  		}
   123  	})
   124  }
   125  
   126  type PageWithoutContent_hugo5379 struct {
   127  	*Page_hugo5379
   128  }
   129  
   130  type pageInit_hugo5379 struct {
   131  	withoutContentInit sync.Once
   132  }
   133  
   134  type pageContentInit_hugo5379 struct {
   135  	contentInit sync.Once // O3
   136  	plainInit   sync.Once // O4
   137  }
   138  
   139  type HugoSites_hugo5379 struct {
   140  	Sites []*Site_hugo5379
   141  }
   142  
   143  func (h *HugoSites_hugo5379) render() {
   144  	for _, s := range h.Sites {
   145  		for _, s2 := range h.Sites {
   146  			s2.preparePagesForRender()
   147  		}
   148  		s.renderPages()
   149  	}
   150  }
   151  
   152  func (h *HugoSites_hugo5379) Build() {
   153  	h.render()
   154  }
   155  
   156  type Pages_hugo5379 []*Page_hugo5379
   157  
   158  type PageCollections_hugo5379 struct {
   159  	Pages Pages_hugo5379
   160  }
   161  
   162  type Site_hugo5379 struct {
   163  	*PageCollections_hugo5379
   164  }
   165  
   166  func (s *Site_hugo5379) preparePagesForRender() {
   167  	for _, p := range s.Pages {
   168  		p.setContentInit()
   169  	}
   170  }
   171  
   172  func (s *Site_hugo5379) renderForLayouts() {
   173  	/// Omit reflections
   174  	for _, p := range s.Pages {
   175  		p.WordCount()
   176  	}
   177  }
   178  
   179  func (s *Site_hugo5379) renderAndWritePage() {
   180  	s.renderForLayouts()
   181  }
   182  
   183  func (s *Site_hugo5379) renderPages() {
   184  	numWorkers := 2
   185  	wg := &sync.WaitGroup{}
   186  
   187  	for i := 0; i < numWorkers; i++ {
   188  		wg.Add(1)
   189  		go pageRenderer_hugo5379(s, wg) // G3
   190  	}
   191  
   192  	wg.Wait()
   193  }
   194  
   195  type sitesBuilder_hugo5379 struct {
   196  	H *HugoSites_hugo5379
   197  }
   198  
   199  func (s *sitesBuilder_hugo5379) Build() *sitesBuilder_hugo5379 {
   200  	return s.build()
   201  }
   202  
   203  func (s *sitesBuilder_hugo5379) build() *sitesBuilder_hugo5379 {
   204  	s.H.Build()
   205  	return s
   206  }
   207  
   208  func (s *sitesBuilder_hugo5379) CreateSitesE() error {
   209  	sites, err := NewHugoSites_hugo5379()
   210  	if err != nil {
   211  		return err
   212  	}
   213  	s.H = sites
   214  	return nil
   215  }
   216  
   217  func (s *sitesBuilder_hugo5379) CreateSites() *sitesBuilder_hugo5379 {
   218  	if err := s.CreateSitesE(); err != nil {
   219  		log.Fatalf("Failed to create sites: %s", err)
   220  	}
   221  	return s
   222  }
   223  
   224  func newHugoSites_hugo5379(sites ...*Site_hugo5379) (*HugoSites_hugo5379, error) {
   225  	h := &HugoSites_hugo5379{Sites: sites}
   226  	return h, nil
   227  }
   228  
   229  func newSite_hugo5379() *Site_hugo5379 {
   230  	c := &PageCollections_hugo5379{}
   231  	s := &Site_hugo5379{
   232  		PageCollections_hugo5379: c,
   233  	}
   234  	return s
   235  }
   236  
   237  func createSitesFromConfig_hugo5379() []*Site_hugo5379 {
   238  	var (
   239  		sites []*Site_hugo5379
   240  	)
   241  
   242  	var s *Site_hugo5379 = newSite_hugo5379()
   243  	sites = append(sites, s)
   244  	return sites
   245  }
   246  
   247  func NewHugoSites_hugo5379() (*HugoSites_hugo5379, error) {
   248  	sites := createSitesFromConfig_hugo5379()
   249  	return newHugoSites_hugo5379(sites...)
   250  }
   251  
   252  func prepareShortcodeForPage_hugo5379(p *PageWithoutContent_hugo5379) map[int]func() error {
   253  	m := make(map[int]func() error)
   254  	m[0] = func() error {
   255  		return renderShortcode_hugo5379(p)
   256  	}
   257  	return m
   258  }
   259  
   260  func renderShortcode_hugo5379(p *PageWithoutContent_hugo5379) error {
   261  	return renderShortcodeWithPage_hugo5379(p)
   262  }
   263  
   264  func renderShortcodeWithPage_hugo5379(p *PageWithoutContent_hugo5379) error {
   265  	/// Omit reflections
   266  	p.WordCount()
   267  	return nil
   268  }
   269  
   270  func createShortcodeRenderers_hugo5379(p *PageWithoutContent_hugo5379) map[int]func() error {
   271  	return prepareShortcodeForPage_hugo5379(p)
   272  }
   273  
   274  func newShortcodeHandler_hugo5379(p *Page_hugo5379) *shortcodeHandler_hugo5379 {
   275  	return &shortcodeHandler_hugo5379{
   276  		p:                      p.withoutContent(),
   277  		contentShortcodes:      make(map[int]func() error),
   278  		contentShortcodesDelta: make(map[int]func() error),
   279  	}
   280  }
   281  
   282  func handleShortcodes_hugo5379(p *PageWithoutContent_hugo5379) error {
   283  	return p.shortcodeState.executeShortcodesForDelta(p)
   284  }
   285  
   286  func pageRenderer_hugo5379(s *Site_hugo5379, wg *sync.WaitGroup) {
   287  	defer wg.Done()
   288  	s.renderAndWritePage()
   289  }
   290  
   291  func Hugo5379() {
   292  	prof := pprof.Lookup("goroutineleak")
   293  	defer func() {
   294  		time.Sleep(100 * time.Millisecond)
   295  		prof.WriteTo(os.Stdout, 2)
   296  	}()
   297  
   298  	for i := 0; i < 100; i++ {
   299  		go func() { // G1
   300  			b := &sitesBuilder_hugo5379{}
   301  			s := b.CreateSites()
   302  			for _, site := range s.H.Sites {
   303  				p := &Page_hugo5379{
   304  					pageInit_hugo5379:        &pageInit_hugo5379{},
   305  					pageContentInit_hugo5379: &pageContentInit_hugo5379{},
   306  					pageWithoutContent:       &PageWithoutContent_hugo5379{},
   307  					contentInit:              sync.Once{},
   308  					contentInitMu:            sync.Mutex{},
   309  					shortcodeState:           nil,
   310  				}
   311  				p.shortcodeState = newShortcodeHandler_hugo5379(p)
   312  				site.Pages = append(site.Pages, p)
   313  			}
   314  			s.Build()
   315  		}()
   316  	}
   317  }
   318  

View as plain text