Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Logging Mutexes #298

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions addrmgr/addrmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ import (

"github.com/gcash/bchd/chaincfg/chainhash"
"github.com/gcash/bchd/wire"
"github.com/gcash/bchutil"
)

// AddrManager provides a concurrency safe address manager for caching potential
// peers on the bitcoin network.
type AddrManager struct {
mtx sync.Mutex
mtx bchutil.Mutex
peersFile string
lookupFunc func(string) ([]net.IP, error)
rand *rand.Rand
Expand All @@ -44,7 +45,7 @@ type AddrManager struct {
quit chan struct{}
nTried int
nNew int
lamtx sync.Mutex
lamtx bchutil.Mutex
localAddresses map[string]*LocalAddress
version int
}
Expand Down Expand Up @@ -1149,6 +1150,9 @@ func (a *AddrManager) LocalAddresses() []*LocalAddress {
// Use Start to begin processing asynchronous address updates.
func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager {
am := AddrManager{
mtx: bchutil.NewMutex("addrmgr.AddrManager.mtx"),
lamtx: bchutil.NewMutex("addrmgr.AddrManager.lamtx"),

peersFile: filepath.Join(dataDir, "peers.json"),
lookupFunc: lookupFunc,
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
Expand Down
4 changes: 3 additions & 1 deletion bchec/ecmh.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ type Multiset struct {
curve *KoblitzCurve
x *big.Int
y *big.Int
mtx sync.RWMutex

// This does not use the logging mutex to avoid cyclic dependencies
mtx sync.RWMutex
}

// NewMultiset returns an empty multiset. The hash of an empty set
Expand Down
10 changes: 6 additions & 4 deletions blockchain/blockindex.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ package blockchain
import (
"math/big"
"sort"
"sync"
"time"

"github.com/gcash/bchd/chaincfg"
"github.com/gcash/bchd/chaincfg/chainhash"
"github.com/gcash/bchd/database"
"github.com/gcash/bchd/wire"
"github.com/gcash/bchutil"
)

// blockStatus is a bit field representing the validation state of the block.
Expand Down Expand Up @@ -229,7 +229,7 @@ type blockIndex struct {
db database.DB
chainParams *chaincfg.Params

sync.RWMutex
bchutil.RWMutex
index map[chainhash.Hash]*blockNode
dirty map[*blockNode]struct{}
}
Expand All @@ -241,8 +241,10 @@ func newBlockIndex(db database.DB, chainParams *chaincfg.Params) *blockIndex {
return &blockIndex{
db: db,
chainParams: chainParams,
index: make(map[chainhash.Hash]*blockNode),
dirty: make(map[*blockNode]struct{}),

RWMutex: bchutil.NewRWMutex("blockchain.blockIndex"),
index: make(map[chainhash.Hash]*blockNode),
dirty: make(map[*blockNode]struct{}),
}
}

Expand Down
14 changes: 9 additions & 5 deletions blockchain/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"container/list"
"fmt"
"math"
"sync"
"time"

"github.com/gcash/bchd/chaincfg"
Expand Down Expand Up @@ -131,7 +130,7 @@ type BlockChain struct {

// chainLock protects concurrent access to the vast majority of the
// fields in this struct below this point.
chainLock sync.RWMutex
chainLock bchutil.RWMutex

// These fields are related to the memory block index. They both have
// their own locks, however they are often also protected by the chain
Expand All @@ -153,7 +152,7 @@ type BlockChain struct {

// orphanLock protects the fields related to handling of orphan blocks.
// They are protected by a combination of the chain lock and the orphan lock.
orphanLock sync.RWMutex
orphanLock bchutil.RWMutex
orphans map[chainhash.Hash]*orphanBlock
prevOrphans map[chainhash.Hash][]*orphanBlock
oldestOrphan *orphanBlock
Expand All @@ -174,7 +173,7 @@ type BlockChain struct {
//
// In addition, some of the fields are stored in the database so the
// chain state can be quickly reconstructed on load.
stateLock sync.RWMutex
stateLock bchutil.RWMutex
stateSnapshot *BestState

// The following caches are used to efficiently keep track of the
Expand Down Expand Up @@ -207,7 +206,7 @@ type BlockChain struct {

// The notifications field stores a slice of callbacks to be executed on
// certain blockchain events.
notificationsLock sync.RWMutex
notificationsLock bchutil.RWMutex
notifications []NotificationCallback

// The following fields are set if the blockchain is configured to prune
Expand Down Expand Up @@ -2272,6 +2271,11 @@ func New(config *Config) (*BlockChain, error) {
pruneDepth: config.PruneDepth,
fastSyncDataDir: config.FastSyncDataDir,
fastSyncDone: make(chan struct{}),

chainLock: bchutil.NewRWMutex("blockchain.BlockChain.chainLock"),
stateLock: bchutil.NewRWMutex("blockchain.BlockChain.stateLock"),
orphanLock: bchutil.NewRWMutex("blockchain.BlockChain.orphanLock"),
notificationsLock: bchutil.NewRWMutex("blockchain.BlockChain.notificationsLock"),
}

// Initialize the chain state from the passed database. When the db
Expand Down
11 changes: 6 additions & 5 deletions blockchain/chainview.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

package blockchain

import (
"sync"
)
import "github.com/gcash/bchutil"

// approxNodesPerWeek is an approximation of the number of new blocks there are
// in a week on average.
Expand Down Expand Up @@ -42,7 +40,7 @@ func fastLog2Floor(n uint32) uint8 {
// The chain view for the branch ending in 6a consists of:
// genesis -> 1 -> 2 -> 3 -> 4a -> 5a -> 6a
type chainView struct {
mtx sync.Mutex
mtx bchutil.Mutex
nodes []*blockNode
}

Expand All @@ -51,7 +49,10 @@ type chainView struct {
// can be updated at any time via the setTip function.
func newChainView(tip *blockNode) *chainView {
// The mutex is intentionally not held since this is a constructor.
var c chainView
c := chainView{
mtx: bchutil.NewMutex("blockchain.chainView.mtx"),
nodes: nil,
}
c.setTip(tip)
return &c
}
Expand Down
5 changes: 3 additions & 2 deletions blockchain/indexers/addrindex.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package indexers
import (
"errors"
"fmt"
"sync"

"github.com/gcash/bchd/blockchain"
"github.com/gcash/bchd/chaincfg"
Expand Down Expand Up @@ -569,7 +568,7 @@ type AddrIndex struct {
// keep an index of all addresses which a given transaction involves.
// This allows fairly efficient updates when transactions are removed
// once they are included into a block.
unconfirmedLock sync.RWMutex
unconfirmedLock bchutil.RWMutex
txnsByAddr map[[addrKeySize]byte]map[chainhash.Hash]*bchutil.Tx
addrsByTx map[chainhash.Hash]map[[addrKeySize]byte]struct{}
}
Expand Down Expand Up @@ -937,6 +936,8 @@ func NewAddrIndex(db database.DB, chainParams *chaincfg.Params) *AddrIndex {
chainParams: chainParams,
txnsByAddr: make(map[[addrKeySize]byte]map[chainhash.Hash]*bchutil.Tx),
addrsByTx: make(map[chainhash.Hash]map[[addrKeySize]byte]struct{}),

unconfirmedLock: bchutil.NewRWMutex("blockchain/indexers.AddrIndex.unconfirmedLock"),
}
}

Expand Down
4 changes: 2 additions & 2 deletions blockchain/indexers/blocklogger.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package indexers
import (
"fmt"
"math"
"sync"
"time"

"github.com/gcash/bchlog"
Expand All @@ -24,7 +23,7 @@ type blockProgressLogger struct {

subsystemLogger bchlog.Logger
progressAction string
sync.Mutex
bchutil.Mutex
}

// newBlockProgressLogger returns a new block progress logger.
Expand All @@ -36,6 +35,7 @@ func newBlockProgressLogger(progressMessage string, logger bchlog.Logger) *block
lastBlockLogTime: time.Now(),
progressAction: progressMessage,
subsystemLogger: logger,
Mutex: bchutil.NewMutex("blockchain/indexers.blockProgressLogger"),
}
}

Expand Down
6 changes: 4 additions & 2 deletions blockchain/mediantime.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ package blockchain
import (
"math"
"sort"
"sync"
"time"

"github.com/gcash/bchutil"
)

const (
Expand Down Expand Up @@ -75,7 +76,7 @@ func (s int64Sorter) Less(i, j int) bool {
// the time offset mechanism in Bitcoin Core. This is necessary because it is
// used in the consensus code.
type medianTime struct {
mtx sync.Mutex
mtx bchutil.Mutex
knownIDs map[string]struct{}
offsets []int64
offsetSecs int64
Expand Down Expand Up @@ -212,6 +213,7 @@ func (m *medianTime) Offset() time.Duration {
// message received from remote peers that successfully connect and negotiate.
func NewMedianTime() MedianTimeSource {
return &medianTime{
mtx: bchutil.NewMutex("blockchain.mediaTime.mtx"),
knownIDs: make(map[string]struct{}),
offsets: make([]int64, 0, maxMedianTimeEntries),
}
Expand Down
5 changes: 3 additions & 2 deletions blockchain/utxocache.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ package blockchain
import (
"container/list"
"fmt"

"github.com/gcash/bchd/txscript"
"sync"

"github.com/gcash/bchd/chaincfg/chainhash"
"github.com/gcash/bchd/database"
Expand Down Expand Up @@ -186,7 +186,7 @@ type utxoCache struct {
// This mutex protects the internal state.
// A simple mutex instead of a read-write mutex is chosen because the main
// read method also possibly does a write on a cache miss.
mtx sync.Mutex
mtx bchutil.Mutex

// cachedEntries keeps the internal cache of the utxo state. The tfModified
// flag indicates that the state of the entry (potentially) deviates from the
Expand All @@ -206,6 +206,7 @@ func newUtxoCache(db database.DB, maxTotalMemoryUsage uint64) *utxoCache {
return &utxoCache{
db: db,
maxTotalMemoryUsage: maxTotalMemoryUsage,
mtx: bchutil.NewMutex("blockchain.utxoCache.mtx"),

cachedEntries: make(map[wire.OutPoint]*UtxoEntry),
}
Expand Down
5 changes: 3 additions & 2 deletions btcjson/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (
"sort"
"strconv"
"strings"
"sync"

"github.com/gcash/bchutil"
)

// UsageFlag define flags that specify additional properties about the
Expand Down Expand Up @@ -84,7 +85,7 @@ type methodInfo struct {

var (
// These fields are used to map the registered types to method names.
registerLock sync.RWMutex
registerLock = bchutil.NewRWMutex("btcjson.registerLock")
methodToConcreteType = make(map[string]reflect.Type)
methodToInfo = make(map[string]methodInfo)
concreteTypeToMethod = make(map[reflect.Type]string)
Expand Down
6 changes: 4 additions & 2 deletions connmgr/connmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"sync"
"sync/atomic"
"time"

"github.com/gcash/bchutil"
)

// maxFailedAttempts is the maximum number of successive failed connection
Expand Down Expand Up @@ -63,7 +65,7 @@ type ConnReq struct {

conn net.Conn
state ConnState
stateMtx sync.RWMutex
stateMtx bchutil.RWMutex
retryCount uint32
}

Expand Down Expand Up @@ -366,7 +368,7 @@ func (cm *ConnManager) NewConnReq() {
return
}

c := &ConnReq{}
c := &ConnReq{stateMtx: bchutil.NewRWMutex("connmgr.ConnReq.stateMtx")}
atomic.StoreUint64(&c.id, atomic.AddUint64(&cm.connReqCount, 1))

// Submit a request of a pending connection attempt to the connection
Expand Down
9 changes: 7 additions & 2 deletions connmgr/dynamicbanscore.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ package connmgr
import (
"fmt"
"math"
"sync"
"time"

"github.com/gcash/bchutil"
)

const (
Expand Down Expand Up @@ -64,7 +65,11 @@ type DynamicBanScore struct {
lastUnix int64
transient float64
persistent uint32
mtx sync.Mutex
mtx bchutil.Mutex
}

func NewDynamicBanScore() DynamicBanScore {
return DynamicBanScore{mtx: bchutil.NewMutex("connmgr.DynamicBanScore.tx")}
}

// String returns the ban score as a human-readable string.
Expand Down
6 changes: 3 additions & 3 deletions connmgr/dynamicbanscore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
// TestDynamicBanScoreDecay tests the exponential decay implemented in
// DynamicBanScore.
func TestDynamicBanScoreDecay(t *testing.T) {
var bs DynamicBanScore
bs := NewDynamicBanScore()
base := time.Now()

r := bs.increase(100, 50, base)
Expand All @@ -35,7 +35,7 @@ func TestDynamicBanScoreDecay(t *testing.T) {
// TestDynamicBanScoreLifetime tests that DynamicBanScore properly yields zero
// once the maximum age is reached.
func TestDynamicBanScoreLifetime(t *testing.T) {
var bs DynamicBanScore
bs := NewDynamicBanScore()
base := time.Now()

bs.increase(0, math.MaxUint32, base)
Expand All @@ -52,7 +52,7 @@ func TestDynamicBanScoreLifetime(t *testing.T) {
// TestDynamicBanScore tests exported functions of DynamicBanScore. Exponential
// decay or other time based behavior is tested by other functions.
func TestDynamicBanScoreReset(t *testing.T) {
var bs DynamicBanScore
bs := NewDynamicBanScore()
if bs.Int() != 0 {
t.Errorf("Initial state is not zero.")
}
Expand Down
Loading