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
|
||||
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)
|
||||
|
||||
// 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.
|
||||
func (b *blockManager) handleDonePeerMsg(peers *list.List, p *peer) {
|
||||
// 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 {
|
||||
peers.Remove(e)
|
||||
break
|
||||
|
|
|
@ -292,7 +292,9 @@ func (mp *txMemPool) removeOrphan(txHash *btcwire.ShaHash) {
|
|||
for _, txIn := range tx.TxIn {
|
||||
originTxHash := txIn.PreviousOutpoint.Hash
|
||||
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 {
|
||||
orphans.Remove(e)
|
||||
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
|
||||
// invoked from the peerHandler goroutine.
|
||||
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 {
|
||||
// Issue an asynchronous reconnect if the peer was a
|
||||
// persistent outbound connection.
|
||||
|
|
Loading…
Reference in a new issue