Patchwork [gccgo] Lock the canonical types map

login
register
mail settings
Submitter Ian Taylor
Date July 21, 2010, 10:13 a.m.
Message ID <mcr4oftdtxp.fsf@google.com>
Download mbox | patch
Permalink /patch/59429/
State New
Headers show

Comments

Ian Taylor - July 21, 2010, 10:13 a.m.
This patch locks the canonical types map, in case different goroutines
use the type reflection code at the same time.  I should have done this
a while ago, but finally ran into a case where it caused trouble.
Committed to gccgo branch.

Ian

Patch

diff -r 5448317e14bb libgo/Makefile.am
--- a/libgo/Makefile.am	Tue Jul 20 05:22:00 2010 -0700
+++ b/libgo/Makefile.am	Wed Jul 21 03:09:11 2010 -0700
@@ -1411,7 +1411,7 @@ 
 	$(CHECK)
 .PHONY: rand/check
 
-reflect/libreflect.a: $(go_reflect_files) runtime.gox strconv.gox
+reflect/libreflect.a: $(go_reflect_files) runtime.gox strconv.gox sync.gox
 	$(BUILDARCHIVE)
 reflect/libreflect.la: reflect/libreflect.a
 reflect/check: $(CHECK_DEPS)
diff -r 5448317e14bb libgo/go/reflect/type.go
--- a/libgo/go/reflect/type.go	Tue Jul 20 05:22:00 2010 -0700
+++ b/libgo/go/reflect/type.go	Wed Jul 21 03:09:11 2010 -0700
@@ -18,6 +18,7 @@ 
 import (
 	"runtime"
 	"strconv"
+	"sync"
 	"unsafe"
 )
 
@@ -597,6 +598,8 @@ 
 // Canonicalize a Type.
 var canonicalType = make(map[string]Type)
 
+var canonicalTypeLock sync.Mutex
+
 func canonicalize(t Type) Type {
 	u := t.uncommon()
 	var s string
@@ -605,10 +608,13 @@ 
 	} else {
 		s = u.PkgPath() + "." + u.Name()
 	}
+	canonicalTypeLock.Lock()
 	if r, ok := canonicalType[s]; ok {
+		canonicalTypeLock.Unlock()
 		return r
 	}
 	canonicalType[s] = t
+	canonicalTypeLock.Unlock()
 	return t
 }