mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
core/state: add some termination checks to prefetcher async shutdowns
This commit is contained in:
parent
e9b599c6a1
commit
8d9f5eee3f
1 changed files with 10 additions and 1 deletions
|
|
@ -95,6 +95,8 @@ func (p *triePrefetcher) report() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, fetcher := range p.fetchers {
|
for _, fetcher := range p.fetchers {
|
||||||
|
fetcher.wait() // ensure the fetcher's idle before poking in its internals
|
||||||
|
|
||||||
if fetcher.root == p.root {
|
if fetcher.root == p.root {
|
||||||
p.accountLoadMeter.Mark(int64(len(fetcher.seen)))
|
p.accountLoadMeter.Mark(int64(len(fetcher.seen)))
|
||||||
p.accountDupMeter.Mark(int64(fetcher.dups))
|
p.accountDupMeter.Mark(int64(fetcher.dups))
|
||||||
|
|
@ -159,6 +161,7 @@ func (p *triePrefetcher) trie(owner common.Hash, root common.Hash) (Trie, error)
|
||||||
// how useful or wasteful the fetcher is.
|
// how useful or wasteful the fetcher is.
|
||||||
func (p *triePrefetcher) used(owner common.Hash, root common.Hash, used [][]byte) {
|
func (p *triePrefetcher) used(owner common.Hash, root common.Hash, used [][]byte) {
|
||||||
if fetcher := p.fetchers[p.trieID(owner, root)]; fetcher != nil {
|
if fetcher := p.fetchers[p.trieID(owner, root)]; fetcher != nil {
|
||||||
|
fetcher.wait() // ensure the fetcher's idle before poking in its internals
|
||||||
fetcher.used = used
|
fetcher.used = used
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -236,13 +239,19 @@ func (sf *subfetcher) schedule(keys [][]byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wait blocks until the subfetcher terminates. This method is used to block on
|
||||||
|
// an async termination before accessing internal fields from the fetcher.
|
||||||
|
func (sf *subfetcher) wait() {
|
||||||
|
<-sf.term
|
||||||
|
}
|
||||||
|
|
||||||
// peek retrieves the fetcher's trie, populated with any pre-fetched data. The
|
// peek retrieves the fetcher's trie, populated with any pre-fetched data. The
|
||||||
// returned trie will be a shallow copy, so modifying it will break subsequent
|
// returned trie will be a shallow copy, so modifying it will break subsequent
|
||||||
// peeks for the original data. The method will block until all the scheduled
|
// peeks for the original data. The method will block until all the scheduled
|
||||||
// data has been loaded and the fethcer terminated.
|
// data has been loaded and the fethcer terminated.
|
||||||
func (sf *subfetcher) peek() Trie {
|
func (sf *subfetcher) peek() Trie {
|
||||||
// Block until the fertcher terminates, then retrieve the trie
|
// Block until the fertcher terminates, then retrieve the trie
|
||||||
<-sf.term
|
sf.wait()
|
||||||
return sf.trie
|
return sf.trie
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue