blob: 6a1bbe9a3f7767058666e1879fe37d015065db52 [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 (
"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()
}()
}
}