mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
fix: add mutex for thread-safe access in indexReader and historyReader
This commit is contained in:
parent
3d2a4cb053
commit
ce3a30967d
2 changed files with 17 additions and 0 deletions
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
|
@ -74,6 +75,8 @@ type indexReader struct {
|
||||||
descList []*indexBlockDesc
|
descList []*indexBlockDesc
|
||||||
readers map[uint32]*blockReader
|
readers map[uint32]*blockReader
|
||||||
state stateIdent
|
state stateIdent
|
||||||
|
|
||||||
|
mu sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadIndexData loads the index data associated with the specified state.
|
// loadIndexData loads the index data associated with the specified state.
|
||||||
|
|
@ -103,6 +106,9 @@ func newIndexReader(db ethdb.KeyValueReader, state stateIdent) (*indexReader, er
|
||||||
// refresh reloads the last section of index data to account for any additional
|
// refresh reloads the last section of index data to account for any additional
|
||||||
// elements that may have been written to disk.
|
// elements that may have been written to disk.
|
||||||
func (r *indexReader) refresh() error {
|
func (r *indexReader) refresh() error {
|
||||||
|
r.mu.Lock()
|
||||||
|
defer r.mu.Unlock()
|
||||||
|
|
||||||
// Release the reader for the last section of index data, as its content
|
// Release the reader for the last section of index data, as its content
|
||||||
// may have been modified by additional elements written to the disk.
|
// may have been modified by additional elements written to the disk.
|
||||||
if len(r.descList) != 0 {
|
if len(r.descList) != 0 {
|
||||||
|
|
@ -130,7 +136,9 @@ func (r *indexReader) readGreaterThan(id uint64) (uint64, error) {
|
||||||
}
|
}
|
||||||
desc := r.descList[index]
|
desc := r.descList[index]
|
||||||
|
|
||||||
|
r.mu.RLock()
|
||||||
br, ok := r.readers[desc.id]
|
br, ok := r.readers[desc.id]
|
||||||
|
r.mu.RUnlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
var err error
|
var err error
|
||||||
blob := readStateIndexBlock(r.state, r.db, desc.id)
|
blob := readStateIndexBlock(r.state, r.db, desc.id)
|
||||||
|
|
@ -138,7 +146,9 @@ func (r *indexReader) readGreaterThan(id uint64) (uint64, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
r.mu.Lock()
|
||||||
r.readers[desc.id] = br
|
r.readers[desc.id] = br
|
||||||
|
r.mu.Unlock()
|
||||||
}
|
}
|
||||||
// The supplied ID is not greater than block.max, ensuring that an element
|
// The supplied ID is not greater than block.max, ensuring that an element
|
||||||
// satisfying the condition can be found.
|
// satisfying the condition can be found.
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
|
@ -104,6 +105,8 @@ type historyReader struct {
|
||||||
disk ethdb.KeyValueReader
|
disk ethdb.KeyValueReader
|
||||||
freezer ethdb.AncientReader
|
freezer ethdb.AncientReader
|
||||||
readers map[string]*indexReaderWithLimitTag
|
readers map[string]*indexReaderWithLimitTag
|
||||||
|
|
||||||
|
mu sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// newHistoryReader constructs the history reader with the supplied db.
|
// newHistoryReader constructs the history reader with the supplied db.
|
||||||
|
|
@ -248,15 +251,19 @@ func (r *historyReader) read(state stateIdentQuery, stateID uint64, lastID uint6
|
||||||
return nil, fmt.Errorf("state history is not fully indexed, requested: %d, indexed: %s", stateID, indexed)
|
return nil, fmt.Errorf("state history is not fully indexed, requested: %d, indexed: %s", stateID, indexed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.mu.RLock()
|
||||||
// Construct the index reader to locate the corresponding history for
|
// Construct the index reader to locate the corresponding history for
|
||||||
// state retrieval
|
// state retrieval
|
||||||
ir, ok := r.readers[state.String()]
|
ir, ok := r.readers[state.String()]
|
||||||
|
r.mu.RUnlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
ir, err = newIndexReaderWithLimitTag(r.disk, state.stateIdent, metadata.Last)
|
ir, err = newIndexReaderWithLimitTag(r.disk, state.stateIdent, metadata.Last)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
r.mu.Lock()
|
||||||
r.readers[state.String()] = ir
|
r.readers[state.String()] = ir
|
||||||
|
r.mu.Unlock()
|
||||||
}
|
}
|
||||||
historyID, err := ir.readGreaterThan(stateID, lastID)
|
historyID, err := ir.readGreaterThan(stateID, lastID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue