Fix data race warning when get cached model struct

This commit is contained in:
Jinzhu 2015-10-01 07:09:00 +08:00
parent 88188b6161
commit 4da2c28d4d
2 changed files with 27 additions and 5 deletions

View File

@ -130,7 +130,7 @@ func (s *DB) LogMode(enable bool) *DB {
} }
func (s *DB) SingularTable(enable bool) { func (s *DB) SingularTable(enable bool) {
modelStructs = map[reflect.Type]*ModelStruct{} modelStructsMap = newModelStructsMap()
s.parent.singularTable = enable s.parent.singularTable = enable
} }

View File

@ -7,17 +7,39 @@ import (
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"github.com/qor/inflection" "github.com/qor/inflection"
) )
var modelStructs = map[reflect.Type]*ModelStruct{}
var DefaultTableNameHandler = func(db *DB, defaultTableName string) string { var DefaultTableNameHandler = func(db *DB, defaultTableName string) string {
return defaultTableName return defaultTableName
} }
type safeModelStructsMap struct {
m map[reflect.Type]*ModelStruct
l *sync.RWMutex
}
func (s *safeModelStructsMap) Set(key reflect.Type, value *ModelStruct) {
s.l.Lock()
defer s.l.Unlock()
s.m[key] = value
}
func (s *safeModelStructsMap) Get(key reflect.Type) *ModelStruct {
s.l.RLock()
defer s.l.RUnlock()
return s.m[key]
}
func newModelStructsMap() *safeModelStructsMap {
return &safeModelStructsMap{l: new(sync.RWMutex), m: make(map[reflect.Type]*ModelStruct)}
}
var modelStructsMap = newModelStructsMap()
type ModelStruct struct { type ModelStruct struct {
PrimaryFields []*StructField PrimaryFields []*StructField
StructFields []*StructField StructFields []*StructField
@ -92,7 +114,7 @@ func (scope *Scope) GetModelStruct() *ModelStruct {
scopeType = scopeType.Elem() scopeType = scopeType.Elem()
} }
if value, ok := modelStructs[scopeType]; ok { if value := modelStructsMap.Get(scopeType); value != nil {
return value return value
} }
@ -370,7 +392,7 @@ func (scope *Scope) GetModelStruct() *ModelStruct {
finished <- true finished <- true
}(finished) }(finished)
modelStructs[scopeType] = &modelStruct modelStructsMap.Set(scopeType, &modelStruct)
<-finished <-finished
modelStruct.cached = true modelStruct.cached = true