mirror of https://github.com/golang/go.git
encoding/gob: fix data race in Register
Fixes #4214. R=golang-dev, dsymonds, bradfitz CC=golang-dev https://golang.org/cl/6637047
This commit is contained in:
parent
e9f0fc8823
commit
e855fcc307
|
|
@ -717,7 +717,9 @@ func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, p ui
|
|||
errorf("name too long (%d bytes): %.20q...", len(name), name)
|
||||
}
|
||||
// The concrete type must be registered.
|
||||
registerLock.RLock()
|
||||
typ, ok := nameToConcreteType[name]
|
||||
registerLock.RUnlock()
|
||||
if !ok {
|
||||
errorf("name not registered for interface: %q", name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -441,7 +441,9 @@ func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv reflect.Value) {
|
|||
}
|
||||
|
||||
ut := userType(iv.Elem().Type())
|
||||
registerLock.RLock()
|
||||
name, ok := concreteTypeToName[ut.base]
|
||||
registerLock.RUnlock()
|
||||
if !ok {
|
||||
errorf("type not registered for interface: %s", ut.base)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -712,6 +712,7 @@ type GobDecoder interface {
|
|||
}
|
||||
|
||||
var (
|
||||
registerLock sync.RWMutex
|
||||
nameToConcreteType = make(map[string]reflect.Type)
|
||||
concreteTypeToName = make(map[reflect.Type]string)
|
||||
)
|
||||
|
|
@ -723,6 +724,8 @@ func RegisterName(name string, value interface{}) {
|
|||
// reserved for nil
|
||||
panic("attempt to register empty name")
|
||||
}
|
||||
registerLock.Lock()
|
||||
defer registerLock.Unlock()
|
||||
ut := userType(reflect.TypeOf(value))
|
||||
// Check for incompatible duplicates. The name must refer to the
|
||||
// same user type, and vice versa.
|
||||
|
|
|
|||
|
|
@ -177,7 +177,10 @@ func TestRegistrationNaming(t *testing.T) {
|
|||
Register(tc.t)
|
||||
|
||||
tct := reflect.TypeOf(tc.t)
|
||||
if ct := nameToConcreteType[tc.name]; ct != tct {
|
||||
registerLock.RLock()
|
||||
ct := nameToConcreteType[tc.name]
|
||||
registerLock.RUnlock()
|
||||
if ct != tct {
|
||||
t.Errorf("nameToConcreteType[%q] = %v, want %v", tc.name, ct, tct)
|
||||
}
|
||||
// concreteTypeToName is keyed off the base type.
|
||||
|
|
|
|||
Loading…
Reference in New Issue