Skip to content

text/template: document concurrency properties for the instances returned by (*Template).New #30281

@bep

Description

@bep
package main

import (
	"fmt"
	"sync"
	"text/template"
)

func main() {
	var wg sync.WaitGroup

	tpl := template.New("")

	for i := 1; i < 20; i++ {
		name := fmt.Sprintf("n%d.txt", i)
		wg.Add(1)
		go func() {
			defer wg.Done()
			tpl.New(name).Parse("Go!")
		}()
	}

	wg.Wait()
}

The above fails with:

fatal error: concurrent map read and map write

goroutine 36 [running]:
runtime.throw(0x1136d33, 0x21)
	/Users/bep/sdk/go1.12beta2/src/runtime/panic.go:617 +0x72 fp=0xc000075d78 sp=0xc000075d48 pc=0x1029d02
runtime.mapaccess1_faststr(0x110d820, 0xc000066210, 0xc000016230, 0x7, 0x0)
	/Users/bep/sdk/go1.12beta2/src/runtime/map_faststr.go:21 +0x464 fp=0xc000075de8 sp=0xc000075d78 pc=0x1010a34
text/template.(*Template).associate(0xc00004a340, 0xc00004a340, 0xc0000ae800, 0xc00006ec01)
	/Users/bep/sdk/go1.12beta2/src/text/template/template.go:217 +0x62 fp=0xc000075e28 sp=0xc000075de8 pc=0x10ec762
text/template.(*Template).AddParseTree(0xc00004a340, 0xc000016230, 0x7, 0xc0000ae800, 0x0, 0x0, 0x0)
	/Users/bep/sdk/go1.12beta2/src/text/template/template.go:128 +0xfa fp=0xc000075e78 sp=0xc000075e28 pc=0x10ebb0a
text/template.(*Template).Parse(0xc00004a340, 0x1131652, 0x3, 0x0, 0x0, 0x0)
	/Users/bep/sdk/go1.12beta2/src/text/template/template.go:203 +0x1f8 fp=0xc000075f78 sp=0xc000075e78 pc=0x10ec528
main.main.func1(0xc000016114, 0xc00004a0c0, 0xc000016230, 0x7)
	/Users/bep/dev/go/bep/temp/main.go:19 +0xfa fp=0xc000075fc0 sp=0xc000075f78 pc=0x10ee17a
runtime.goexit()
	/Users/bep/sdk/go1.12beta2/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc000075fc8 sp=0xc000075fc0 pc=0x1052f41
created by main.main
	/Users/bep/dev/go/bep/temp/main.go:17 +0x13b

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc000016114)
	/Users/bep/sdk/go1.12beta2/src/runtime/sema.go:56 +0x39
sync.(*WaitGroup).Wait(0xc000016114)
	/Users/bep/sdk/go1.12beta2/src/sync/waitgroup.go:130 +0x65
main.main()
	/Users/bep/dev/go/bep/temp/main.go:23 +0x161
Error: process exited with code 2.

I'm currently running go1.12beta2 (yes, I know), but I have had this failure on earlier versions, too.

Note that I'm not saying that this is a bug (the doc for Parse isn't clear on this), but as this has hit me more than once in real programs, I think at least a documentation update is needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DocumentationIssues describing a change to documentation.FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions