Correct all list/container loops that remove items.
It is not safe to remove an item from a container/list while iterating the list without first saving the next pointer since removing the item nils the internal list element's next pointer.
This commit is contained in:
parent
ff2c88e3b4
commit
219a6131f4
3 changed files with 12 additions and 4 deletions
|
@ -95,7 +95,9 @@ func (b *blockManager) startSync(peers *list.List) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var bestPeer *peer
|
var bestPeer *peer
|
||||||
for e := peers.Front(); e != nil; e = e.Next() {
|
var enext *list.Element
|
||||||
|
for e := peers.Front(); e != nil; e = enext {
|
||||||
|
enext = e.Next()
|
||||||
p := e.Value.(*peer)
|
p := e.Value.(*peer)
|
||||||
|
|
||||||
// Remove sync candidate peers that are no longer candidates due
|
// Remove sync candidate peers that are no longer candidates due
|
||||||
|
@ -187,7 +189,9 @@ func (b *blockManager) handleNewPeerMsg(peers *list.List, p *peer) {
|
||||||
// is invoked from the syncHandler goroutine.
|
// is invoked from the syncHandler goroutine.
|
||||||
func (b *blockManager) handleDonePeerMsg(peers *list.List, p *peer) {
|
func (b *blockManager) handleDonePeerMsg(peers *list.List, p *peer) {
|
||||||
// Remove the peer from the list of candidate peers.
|
// Remove the peer from the list of candidate peers.
|
||||||
for e := peers.Front(); e != nil; e = e.Next() {
|
var enext *list.Element
|
||||||
|
for e := peers.Front(); e != nil; e = enext {
|
||||||
|
enext = e.Next()
|
||||||
if e.Value == p {
|
if e.Value == p {
|
||||||
peers.Remove(e)
|
peers.Remove(e)
|
||||||
break
|
break
|
||||||
|
|
|
@ -292,7 +292,9 @@ func (mp *txMemPool) removeOrphan(txHash *btcwire.ShaHash) {
|
||||||
for _, txIn := range tx.TxIn {
|
for _, txIn := range tx.TxIn {
|
||||||
originTxHash := txIn.PreviousOutpoint.Hash
|
originTxHash := txIn.PreviousOutpoint.Hash
|
||||||
if orphans, exists := mp.orphansByPrev[originTxHash]; exists {
|
if orphans, exists := mp.orphansByPrev[originTxHash]; exists {
|
||||||
for e := orphans.Front(); e != nil; e = e.Next() {
|
var enext *list.Element
|
||||||
|
for e := orphans.Front(); e != nil; e = enext {
|
||||||
|
enext = e.Next()
|
||||||
if e.Value.(*btcwire.MsgTx) == tx {
|
if e.Value.(*btcwire.MsgTx) == tx {
|
||||||
orphans.Remove(e)
|
orphans.Remove(e)
|
||||||
break
|
break
|
||||||
|
|
|
@ -116,7 +116,9 @@ func (s *server) handleAddPeerMsg(peers *list.List, banned map[string]time.Time,
|
||||||
// handleDonePeerMsg deals with peers that have signalled they are done. It is
|
// handleDonePeerMsg deals with peers that have signalled they are done. It is
|
||||||
// invoked from the peerHandler goroutine.
|
// invoked from the peerHandler goroutine.
|
||||||
func (s *server) handleDonePeerMsg(peers *list.List, p *peer) bool {
|
func (s *server) handleDonePeerMsg(peers *list.List, p *peer) bool {
|
||||||
for e := peers.Front(); e != nil; e = e.Next() {
|
var enext *list.Element
|
||||||
|
for e := peers.Front(); e != nil; e = enext {
|
||||||
|
enext = e.Next()
|
||||||
if e.Value == p {
|
if e.Value == p {
|
||||||
// Issue an asynchronous reconnect if the peer was a
|
// Issue an asynchronous reconnect if the peer was a
|
||||||
// persistent outbound connection.
|
// persistent outbound connection.
|
||||||
|
|
Loading…
Add table
Reference in a new issue