Race fix. Changes modelStructsMap implementation from map with mutex to sync.Map (#2022)

* fix (https://github.com/jinzhu/gorm/issues/1407)

* changed map with mutex to sync.Map (https://github.com/jinzhu/gorm/issues/1407)

* removed newModelStructsMap func

* commit to rerun pipeline, comment changed
This commit is contained in:
Artemij Shepelev 2018-08-19 02:09:21 +03:00 committed by Jinzhu
parent 409121d9e3
commit 0e04d414d5
2 changed files with 7 additions and 27 deletions

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"strings" "strings"
"sync"
"time" "time"
) )
@ -162,7 +163,7 @@ func (s *DB) HasBlockGlobalUpdate() bool {
// SingularTable use singular table by default // SingularTable use singular table by default
func (s *DB) SingularTable(enable bool) { func (s *DB) SingularTable(enable bool) {
modelStructsMap = newModelStructsMap() modelStructsMap = sync.Map{}
s.parent.singularTable = enable s.parent.singularTable = enable
} }

View File

@ -17,28 +17,7 @@ var DefaultTableNameHandler = func(db *DB, defaultTableName string) string {
return defaultTableName return defaultTableName
} }
type safeModelStructsMap struct { var modelStructsMap sync.Map
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()
// ModelStruct model definition // ModelStruct model definition
type ModelStruct struct { type ModelStruct struct {
@ -48,7 +27,7 @@ type ModelStruct struct {
defaultTableName string defaultTableName string
} }
// TableName get model's table name // TableName returns model's table name
func (s *ModelStruct) TableName(db *DB) string { func (s *ModelStruct) TableName(db *DB) string {
if s.defaultTableName == "" && db != nil && s.ModelType != nil { if s.defaultTableName == "" && db != nil && s.ModelType != nil {
// Set default table name // Set default table name
@ -152,8 +131,8 @@ func (scope *Scope) GetModelStruct() *ModelStruct {
} }
// Get Cached model struct // Get Cached model struct
if value := modelStructsMap.Get(reflectType); value != nil { if value, ok := modelStructsMap.Load(reflectType); ok && value != nil {
return value return value.(*ModelStruct)
} }
modelStruct.ModelType = reflectType modelStruct.ModelType = reflectType
@ -601,7 +580,7 @@ func (scope *Scope) GetModelStruct() *ModelStruct {
} }
} }
modelStructsMap.Set(reflectType, &modelStruct) modelStructsMap.Store(reflectType, &modelStruct)
return &modelStruct return &modelStruct
} }