core/rawdb: fix data race between Retrieve and Close (#20919)

* core/rawdb: fixed data race between retrieve and close

closes https://github.com/ethereum/go-ethereum/issues/20420

* core/rawdb: use non-atomic load while holding mutex
release/1.9
Marius van der Wijden 5 years ago committed by GitHub
parent eb2fd823b2
commit 2a836bb259
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      core/rawdb/freezer_table.go

@ -541,20 +541,22 @@ func (t *freezerTable) getBounds(item uint64) (uint32, uint32, uint32, error) {
// Retrieve looks up the data offset of an item with the given number and retrieves // Retrieve looks up the data offset of an item with the given number and retrieves
// the raw binary blob from the data file. // the raw binary blob from the data file.
func (t *freezerTable) Retrieve(item uint64) ([]byte, error) { func (t *freezerTable) Retrieve(item uint64) ([]byte, error) {
t.lock.RLock()
// Ensure the table and the item is accessible // Ensure the table and the item is accessible
if t.index == nil || t.head == nil { if t.index == nil || t.head == nil {
t.lock.RUnlock()
return nil, errClosed return nil, errClosed
} }
if atomic.LoadUint64(&t.items) <= item { if atomic.LoadUint64(&t.items) <= item {
t.lock.RUnlock()
return nil, errOutOfBounds return nil, errOutOfBounds
} }
// Ensure the item was not deleted from the tail either // Ensure the item was not deleted from the tail either
offset := atomic.LoadUint32(&t.itemOffset) if uint64(t.itemOffset) > item {
if uint64(offset) > item { t.lock.RUnlock()
return nil, errOutOfBounds return nil, errOutOfBounds
} }
t.lock.RLock() startOffset, endOffset, filenum, err := t.getBounds(item - uint64(t.itemOffset))
startOffset, endOffset, filenum, err := t.getBounds(item - uint64(offset))
if err != nil { if err != nil {
t.lock.RUnlock() t.lock.RUnlock()
return nil, err return nil, err

Loading…
Cancel
Save