mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 14:52:17 +00:00
fix race conditions
This commit is contained in:
parent
b0755c938a
commit
946fa21dc7
3
Makefile
3
Makefile
@ -3,6 +3,9 @@ all: build
|
|||||||
build:
|
build:
|
||||||
go build -o tendermint github.com/tendermint/tendermint/cmd
|
go build -o tendermint github.com/tendermint/tendermint/cmd
|
||||||
|
|
||||||
|
build_race:
|
||||||
|
go build -race -o tendermint github.com/tendermint/tendermint/cmd
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test github.com/tendermint/tendermint/...
|
go test github.com/tendermint/tendermint/...
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TypeInfo struct {
|
type TypeInfo struct {
|
||||||
@ -27,8 +28,23 @@ type HasTypeByte interface {
|
|||||||
TypeByte() byte
|
TypeByte() byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: do not access typeInfos directly, but call GetTypeInfo()
|
||||||
|
var typeInfosMtx sync.Mutex
|
||||||
var typeInfos = map[reflect.Type]*TypeInfo{}
|
var typeInfos = map[reflect.Type]*TypeInfo{}
|
||||||
|
|
||||||
|
func GetTypeInfo(rt reflect.Type) *TypeInfo {
|
||||||
|
typeInfosMtx.Lock()
|
||||||
|
defer typeInfosMtx.Unlock()
|
||||||
|
info := typeInfos[rt]
|
||||||
|
if info == nil {
|
||||||
|
info = &TypeInfo{Type: rt}
|
||||||
|
RegisterType(info)
|
||||||
|
}
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registers and possibly modifies the TypeInfo.
|
||||||
|
// NOTE: not goroutine safe, so only call upon program init.
|
||||||
func RegisterType(info *TypeInfo) *TypeInfo {
|
func RegisterType(info *TypeInfo) *TypeInfo {
|
||||||
|
|
||||||
// Register the type info
|
// Register the type info
|
||||||
@ -74,10 +90,7 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get typeInfo
|
// Get typeInfo
|
||||||
typeInfo := typeInfos[rt]
|
typeInfo := GetTypeInfo(rt)
|
||||||
if typeInfo == nil {
|
|
||||||
typeInfo = RegisterType(&TypeInfo{Type: rt})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom decoder
|
// Custom decoder
|
||||||
if typeInfo.Decoder != nil {
|
if typeInfo.Decoder != nil {
|
||||||
@ -178,10 +191,7 @@ func readReflect(rv reflect.Value, rt reflect.Type, r io.Reader, n *int64, err *
|
|||||||
func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err *error) {
|
func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err *error) {
|
||||||
|
|
||||||
// Get typeInfo
|
// Get typeInfo
|
||||||
typeInfo := typeInfos[rt]
|
typeInfo := GetTypeInfo(rt)
|
||||||
if typeInfo == nil {
|
|
||||||
typeInfo = RegisterType(&TypeInfo{Type: rt})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom encoder, say for an interface type rt.
|
// Custom encoder, say for an interface type rt.
|
||||||
if typeInfo.Encoder != nil {
|
if typeInfo.Encoder != nil {
|
||||||
@ -193,11 +203,8 @@ func writeReflect(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err
|
|||||||
if rt.Kind() == reflect.Interface {
|
if rt.Kind() == reflect.Interface {
|
||||||
rv = rv.Elem()
|
rv = rv.Elem()
|
||||||
rt = rv.Type()
|
rt = rv.Type()
|
||||||
typeInfo = typeInfos[rt]
|
|
||||||
// If interface type, get typeInfo of underlying type.
|
// If interface type, get typeInfo of underlying type.
|
||||||
if typeInfo == nil {
|
typeInfo = GetTypeInfo(rt)
|
||||||
typeInfo = RegisterType(&TypeInfo{Type: rt})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dereference pointer
|
// Dereference pointer
|
||||||
|
@ -323,7 +323,11 @@ OUTER_LOOP:
|
|||||||
|
|
||||||
trySendVote := func(voteSet *VoteSet, peerVoteSet BitArray) (sent bool) {
|
trySendVote := func(voteSet *VoteSet, peerVoteSet BitArray) (sent bool) {
|
||||||
// TODO: give priority to our vote.
|
// TODO: give priority to our vote.
|
||||||
|
// peerVoteSet BitArray is being accessed concurrently with
|
||||||
|
// writes from Receive() routines. We must lock like so here:
|
||||||
|
ps.mtx.Lock()
|
||||||
index, ok := voteSet.BitArray().Sub(peerVoteSet).PickRandom()
|
index, ok := voteSet.BitArray().Sub(peerVoteSet).PickRandom()
|
||||||
|
ps.mtx.Unlock()
|
||||||
if ok {
|
if ok {
|
||||||
vote := voteSet.GetByIndex(index)
|
vote := voteSet.GetByIndex(index)
|
||||||
// NOTE: vote may be a commit.
|
// NOTE: vote may be a commit.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user