diff --git a/rpc/model/command_info.go b/rpc/model/command_info.go index c2c13c243..f7e442a81 100644 --- a/rpc/model/command_info.go +++ b/rpc/model/command_info.go @@ -11,22 +11,22 @@ import ( ) func concreteTypeToMethodWithRLock(rt reflect.Type) (string, bool) { - registerLock.RLock() - defer registerLock.RUnlock() + methodsLock.RLock() + defer methodsLock.RUnlock() method, ok := concreteTypeToMethod[rt] return method, ok } func methodToInfoWithRLock(method string) (methodInfo, bool) { - registerLock.RLock() - defer registerLock.RUnlock() + methodsLock.RLock() + defer methodsLock.RUnlock() info, ok := methodToInfo[method] return info, ok } func methodConcreteTypeAndInfoWithRLock(method string) (reflect.Type, methodInfo, bool) { - registerLock.RLock() - defer registerLock.RUnlock() + methodsLock.RLock() + defer methodsLock.RUnlock() rtp, ok := methodToConcreteType[method] if !ok { return nil, methodInfo{}, false @@ -245,8 +245,9 @@ func methodUsageText(rtp reflect.Type, defaults map[int]reflect.Value, method st func MethodUsageText(method string) (string, error) { // Look up details about the provided method and error out if not // registered. - registerLock.RLock() - defer registerLock.RUnlock() + methodsLock.Lock() // Take write lock to protect methodToInfo from concurrent read and write + defer methodsLock.Unlock() + rtp, ok := methodToConcreteType[method] info := methodToInfo[method] if !ok { diff --git a/rpc/model/register.go b/rpc/model/register.go index 28d5f0ec9..7b6226db5 100644 --- a/rpc/model/register.go +++ b/rpc/model/register.go @@ -79,7 +79,7 @@ type methodInfo struct { var ( // These fields are used to map the registered types to method names. - registerLock sync.RWMutex + methodsLock sync.RWMutex methodToConcreteType = make(map[string]reflect.Type) methodToInfo = make(map[string]methodInfo) concreteTypeToMethod = make(map[reflect.Type]string) @@ -150,8 +150,8 @@ func isAcceptableKind(kind reflect.Kind) bool { // is recommended to simply pass a nil pointer cast to the appropriate type. // For example, (*FooCmd)(nil). func RegisterCmd(method string, cmd interface{}, flags UsageFlag) error { - registerLock.Lock() - defer registerLock.Unlock() + methodsLock.Lock() + defer methodsLock.Unlock() if _, ok := methodToConcreteType[method]; ok { str := fmt.Sprintf("method %q is already registered", method) @@ -274,8 +274,8 @@ func MustRegisterCommand(method string, cmd interface{}, flags UsageFlag) { // RegisteredCmdMethods returns a sorted list of methods for all registered // commands. func RegisteredCmdMethods() []string { - registerLock.Lock() - defer registerLock.Unlock() + methodsLock.Lock() + defer methodsLock.Unlock() methods := make([]string, 0, len(methodToInfo)) for k := range methodToInfo {