// 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" "log" "os" "runtime/pprof" "sync" "time" ) func init() { register("Hugo5379", Hugo5379) } type shortcodeHandler_hugo5379 struct { p *PageWithoutContent_hugo5379 contentShortcodes map[int]func() error contentShortcodesDelta map[int]func() error init sync.Once // O1 } func (s *shortcodeHandler_hugo5379) executeShortcodesForDelta(p *PageWithoutContent_hugo5379) error { for k, _ := range s.contentShortcodesDelta { render := s.contentShortcodesDelta[k] if err := render(); err != nil { continue } } return nil } func (s *shortcodeHandler_hugo5379) updateDelta() { s.init.Do(func() { s.contentShortcodes = createShortcodeRenderers_hugo5379(s.p.withoutContent()) }) delta := make(map[int]func() error) for k, v := range s.contentShortcodes { if _, ok := delta[k]; !ok { delta[k] = v } } s.contentShortcodesDelta = delta } type Page_hugo5379 struct { *pageInit_hugo5379 *pageContentInit_hugo5379 pageWithoutContent *PageWithoutContent_hugo5379 contentInit sync.Once // O2 contentInitMu sync.Mutex // L1 shortcodeState *shortcodeHandler_hugo5379 } func (p *Page_hugo5379) WordCount() { p.initContentPlainAndMeta() } func (p *Page_hugo5379) initContentPlainAndMeta() { p.initContent() p.initPlain(true) } func (p *Page_hugo5379) initPlain(lock bool) { p.plainInit.Do(func() { if lock { /// Double locking here. p.contentInitMu.Lock() defer p.contentInitMu.Unlock() } }) } func (p *Page_hugo5379) withoutContent() *PageWithoutContent_hugo5379 { p.pageInit_hugo5379.withoutContentInit.Do(func() { p.pageWithoutContent = &PageWithoutContent_hugo5379{Page_hugo5379: p} }) return p.pageWithoutContent } func (p *Page_hugo5379) prepareForRender() error { var err error if err = handleShortcodes_hugo5379(p.withoutContent()); err != nil { return err } return nil } func (p *Page_hugo5379) setContentInit() { p.shortcodeState.updateDelta() } func (p *Page_hugo5379) initContent() { p.contentInit.Do(func() { ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) defer cancel() c := make(chan error, 1) go func() { // G2 var err error p.contentInitMu.Lock() // first lock here defer p.contentInitMu.Unlock() err = p.prepareForRender() if err != nil { c <- err return } c <- err }() select { case <-ctx.Done(): case <-c: } }) } type PageWithoutContent_hugo5379 struct { *Page_hugo5379 } type pageInit_hugo5379 struct { withoutContentInit sync.Once } type pageContentInit_hugo5379 struct { contentInit sync.Once // O3 plainInit sync.Once // O4 } type HugoSites_hugo5379 struct { Sites []*Site_hugo5379 } func (h *HugoSites_hugo5379) render() { for _, s := range h.Sites { for _, s2 := range h.Sites { s2.preparePagesForRender() } s.renderPages() } } func (h *HugoSites_hugo5379) Build() { h.render() } type Pages_hugo5379 []*Page_hugo5379 type PageCollections_hugo5379 struct { Pages Pages_hugo5379 } type Site_hugo5379 struct { *PageCollections_hugo5379 } func (s *Site_hugo5379) preparePagesForRender() { for _, p := range s.Pages { p.setContentInit() } } func (s *Site_hugo5379) renderForLayouts() { /// Omit reflections for _, p := range s.Pages { p.WordCount() } } func (s *Site_hugo5379) renderAndWritePage() { s.renderForLayouts() } func (s *Site_hugo5379) renderPages() { numWorkers := 2 wg := &sync.WaitGroup{} for i := 0; i < numWorkers; i++ { wg.Add(1) go pageRenderer_hugo5379(s, wg) // G3 } wg.Wait() } type sitesBuilder_hugo5379 struct { H *HugoSites_hugo5379 } func (s *sitesBuilder_hugo5379) Build() *sitesBuilder_hugo5379 { return s.build() } func (s *sitesBuilder_hugo5379) build() *sitesBuilder_hugo5379 { s.H.Build() return s } func (s *sitesBuilder_hugo5379) CreateSitesE() error { sites, err := NewHugoSites_hugo5379() if err != nil { return err } s.H = sites return nil } func (s *sitesBuilder_hugo5379) CreateSites() *sitesBuilder_hugo5379 { if err := s.CreateSitesE(); err != nil { log.Fatalf("Failed to create sites: %s", err) } return s } func newHugoSites_hugo5379(sites ...*Site_hugo5379) (*HugoSites_hugo5379, error) { h := &HugoSites_hugo5379{Sites: sites} return h, nil } func newSite_hugo5379() *Site_hugo5379 { c := &PageCollections_hugo5379{} s := &Site_hugo5379{ PageCollections_hugo5379: c, } return s } func createSitesFromConfig_hugo5379() []*Site_hugo5379 { var ( sites []*Site_hugo5379 ) var s *Site_hugo5379 = newSite_hugo5379() sites = append(sites, s) return sites } func NewHugoSites_hugo5379() (*HugoSites_hugo5379, error) { sites := createSitesFromConfig_hugo5379() return newHugoSites_hugo5379(sites...) } func prepareShortcodeForPage_hugo5379(p *PageWithoutContent_hugo5379) map[int]func() error { m := make(map[int]func() error) m[0] = func() error { return renderShortcode_hugo5379(p) } return m } func renderShortcode_hugo5379(p *PageWithoutContent_hugo5379) error { return renderShortcodeWithPage_hugo5379(p) } func renderShortcodeWithPage_hugo5379(p *PageWithoutContent_hugo5379) error { /// Omit reflections p.WordCount() return nil } func createShortcodeRenderers_hugo5379(p *PageWithoutContent_hugo5379) map[int]func() error { return prepareShortcodeForPage_hugo5379(p) } func newShortcodeHandler_hugo5379(p *Page_hugo5379) *shortcodeHandler_hugo5379 { return &shortcodeHandler_hugo5379{ p: p.withoutContent(), contentShortcodes: make(map[int]func() error), contentShortcodesDelta: make(map[int]func() error), } } func handleShortcodes_hugo5379(p *PageWithoutContent_hugo5379) error { return p.shortcodeState.executeShortcodesForDelta(p) } func pageRenderer_hugo5379(s *Site_hugo5379, wg *sync.WaitGroup) { defer wg.Done() s.renderAndWritePage() } func Hugo5379() { prof := pprof.Lookup("goroutineleak") defer func() { time.Sleep(100 * time.Millisecond) prof.WriteTo(os.Stdout, 2) }() for i := 0; i < 100; i++ { go func() { // G1 b := &sitesBuilder_hugo5379{} s := b.CreateSites() for _, site := range s.H.Sites { p := &Page_hugo5379{ pageInit_hugo5379: &pageInit_hugo5379{}, pageContentInit_hugo5379: &pageContentInit_hugo5379{}, pageWithoutContent: &PageWithoutContent_hugo5379{}, contentInit: sync.Once{}, contentInitMu: sync.Mutex{}, shortcodeState: nil, } p.shortcodeState = newShortcodeHandler_hugo5379(p) site.Pages = append(site.Pages, p) } s.Build() }() } }