mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
p2p/enode: sync BufferIter Close and Next
When Close was called while Next was active, and there was a race on the closed channel. If Close finished before closed was received, This happened: goroutine 22716 [chan send, 5 minutes]: github.com/ethereum/go-ethereum/p2p/enode.NewBufferIter.func1() github.com/ethereum/go-ethereum/p2p/enode/iter.go:219 +0x77 created by github.com/ethereum/go-ethereum/p2p/enode.NewBufferIter in goroutine 1 github.com/ethereum/go-ethereum/p2p/enode/iter.go:216 +0xd8 goroutine 22714 [chan receive (nil chan), 1 minutes]: github.com/ethereum/go-ethereum/p2p/enode.(*BufferIter).Next(0xc00505fea0) github.com/ethereum/go-ethereum/p2p/enode/iter.go:226 +0x2d github.com/ethereum/go-ethereum/p2p/enode.AsyncFilter.func1() github.com/ethereum/go-ethereum/p2p/enode/iter.go:151 +0x5f created by github.com/ethereum/go-ethereum/p2p/enode.AsyncFilter in goroutine 1 github.com/ethereum/go-ethereum/p2p/enode/iter.go:146 +0x156 Signed-off-by: Csaba Kiraly <csaba.kiraly@gmail.com>
This commit is contained in:
parent
83e5556eb4
commit
0608eb20e9
1 changed files with 9 additions and 0 deletions
|
|
@ -239,6 +239,7 @@ type BufferIter struct {
|
||||||
buffer chan *Node
|
buffer chan *Node
|
||||||
head *Node
|
head *Node
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBufferIter creates a new pre-fetch buffer of a given size.
|
// NewBufferIter creates a new pre-fetch buffer of a given size.
|
||||||
|
|
@ -266,6 +267,9 @@ func NewBufferIter(it Iterator, size int) *BufferIter {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BufferIter) Next() bool {
|
func (b *BufferIter) Next() bool {
|
||||||
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case b.head = <-b.buffer:
|
case b.head = <-b.buffer:
|
||||||
case <-b.closed:
|
case <-b.closed:
|
||||||
|
|
@ -275,6 +279,8 @@ func (b *BufferIter) Next() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BufferIter) Node() *Node {
|
func (b *BufferIter) Node() *Node {
|
||||||
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
return b.head
|
return b.head
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,6 +288,9 @@ func (b *BufferIter) Close() {
|
||||||
// Close the wrapped iterator first.
|
// Close the wrapped iterator first.
|
||||||
b.it.Close()
|
b.it.Close()
|
||||||
close(b.closed)
|
close(b.closed)
|
||||||
|
// Wait for Next to terminate, then drain the buffer.
|
||||||
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
for range b.buffer {
|
for range b.buffer {
|
||||||
}
|
}
|
||||||
b.buffer = nil
|
b.buffer = nil
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue