Fix up some crashes around piece availability

This commit is contained in:
Matt Joiner 2021-05-20 14:01:31 +10:00
parent 1a27e14391
commit b43987fcc8
2 changed files with 21 additions and 10 deletions

View File

@ -396,7 +396,9 @@ func (p *Peer) close() {
p.discardPieceInclination()
p._pieceRequestOrder.Clear()
p.peerImpl.onClose()
p.t.decPeerPieceAvailability(p)
if p.t != nil {
p.t.decPeerPieceAvailability(p)
}
for _, f := range p.callbacks.PeerClosed {
f(p)
}
@ -1651,19 +1653,23 @@ func (cn *Peer) peerMaxRequests() int {
return cn.PeerMaxRequests
}
// Returns the pieces the peer has claimed to have.
// Returns the pieces the peer could have based on their claims. If we don't know how many pieces
// are in the torrent, it could be a very large range the peer has sent HaveAll.
func (cn *PeerConn) PeerPieces() bitmap.Bitmap {
cn.locker().RLock()
defer cn.locker().RUnlock()
return cn.newPeerPieces()
}
// Returns a new Bitmap that includes bits for all pieces the peer claims to have.
// Returns a new Bitmap that includes bits for all pieces the peer could have based on their claims.
func (cn *Peer) newPeerPieces() bitmap.Bitmap {
ret := cn._peerPieces.Copy()
if cn.peerSentHaveAll {
ret.AddRange(0, bitmap.BitRange(cn.t.numPieces()))
if cn.t.haveInfo() {
ret.AddRange(0, bitmap.BitRange(cn.t.numPieces()))
} else {
ret.AddRange(0, bitmap.ToEnd)
}
}
return ret
}

View File

@ -436,16 +436,18 @@ func (t *Torrent) onSetInfo() {
p.onGotInfo(t.info)
})
for i := range t.pieces {
t.updatePieceCompletion(pieceIndex(i))
p := &t.pieces[i]
if !p.storageCompletionOk {
// t.logger.Printf("piece %s completion unknown, queueing check", p)
t.queuePieceCheck(pieceIndex(i))
}
// Need to add availability before updating piece completion, as that may result in conns
// being dropped.
if p.availability != 0 {
panic(p.availability)
}
p.availability = int64(t.pieceAvailabilityFromPeers(i))
t.updatePieceCompletion(pieceIndex(i))
if !p.storageCompletionOk {
// t.logger.Printf("piece %s completion unknown, queueing check", p)
t.queuePieceCheck(pieceIndex(i))
}
}
t.cl.event.Broadcast()
t.gotMetainfo.Set()
@ -1374,6 +1376,9 @@ func (t *Torrent) deletePeerConn(c *PeerConn) (ret bool) {
}
func (t *Torrent) decPeerPieceAvailability(p *Peer) {
if !t.haveInfo() {
return
}
p.newPeerPieces().IterTyped(func(i int) bool {
p.t.decPieceAvailability(i)
return true