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:
Dave Collins 2013-10-07 09:04:11 -05:00
parent ff2c88e3b4
commit 219a6131f4
3 changed files with 12 additions and 4 deletions

View file

@ -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

View file

@ -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

View file

@ -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.