Fix up some crashes around piece availability
This commit is contained in:
parent
1a27e14391
commit
b43987fcc8
16
peerconn.go
16
peerconn.go
|
@ -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
|
||||
}
|
||||
|
|
15
torrent.go
15
torrent.go
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue