From 8cea4288028ea49906a9163fb7e862d77fa4f123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Fri, 18 Dec 2015 09:54:46 +0100 Subject: [PATCH] Fix data race in non-renderable pages Fixes #1601 --- hugolib/page.go | 5 +++++ hugolib/site.go | 37 +++++++++++++++++++++---------------- hugolib/site_test.go | 4 ++-- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/hugolib/page.go b/hugolib/page.go index 13a3c283e..0a2a4a5e9 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -66,6 +66,7 @@ type Page struct { contentType string renderable bool Layout string + layoutsCalculated []string linkTitle string frontmatter []byte rawContent []byte @@ -288,6 +289,10 @@ func (p *Page) Section() string { } func (p *Page) layouts(l ...string) []string { + if len(p.layoutsCalculated) > 0 { + return p.layoutsCalculated + } + if p.Layout != "" { return layouts(p.Type(), p.Layout) } diff --git a/hugolib/site.go b/hugolib/site.go index 4e46879c9..aedba14ce 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -920,6 +920,26 @@ func (s *Site) RenderPages() error { procs := getGoMaxProcs() + // this cannot be fanned out to multiple Go routines + // See issue #1601 + // TODO(bep): Check the IsRenderable logic. + for _, p := range s.Pages { + var layouts []string + if !p.IsRenderable() { + self := "__" + p.TargetPath() + _, err := s.Tmpl.New(self).Parse(string(p.Content)) + if err != nil { + results <- err + continue + } + layouts = append(layouts, self) + } else { + layouts = append(layouts, p.layouts()...) + layouts = append(layouts, "_default/single.html") + } + p.layoutsCalculated = layouts + } + wg := &sync.WaitGroup{} for i := 0; i < procs*4; i++ { @@ -951,22 +971,7 @@ func (s *Site) RenderPages() error { func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.WaitGroup) { defer wg.Done() for p := range pages { - var layouts []string - - if !p.IsRenderable() { - self := "__" + p.TargetPath() - _, err := s.Tmpl.New(self).Parse(string(p.Content)) - if err != nil { - results <- err - continue - } - layouts = append(layouts, self) - } else { - layouts = append(layouts, p.layouts()...) - layouts = append(layouts, "_default/single.html") - } - - err := s.renderAndWritePage("page "+p.FullFilePath(), p.TargetPath(), p, s.appendThemeTemplates(layouts)...) + err := s.renderAndWritePage("page "+p.FullFilePath(), p.TargetPath(), p, s.appendThemeTemplates(p.layouts())...) if err != nil { results <- err } diff --git a/hugolib/site_test.go b/hugolib/site_test.go index 1405210cc..1c0729c09 100644 --- a/hugolib/site_test.go +++ b/hugolib/site_test.go @@ -158,7 +158,7 @@ func TestRenderThing(t *testing.T) { templateName := fmt.Sprintf("foobar%d", i) err = s.addTemplate(templateName, test.template) if err != nil { - t.Fatalf("Unable to add template") + t.Fatalf("Unable to add template: %s", err) } p.Content = template.HTML(p.Content) @@ -203,7 +203,7 @@ func TestRenderThingOrDefault(t *testing.T) { templateName := fmt.Sprintf("default%d", i) err = s.addTemplate(templateName, test.template) if err != nil { - t.Fatalf("Unable to add template") + t.Fatalf("Unable to add template: %s", err) } var err2 error