return nil
}
-func (cn *PeerConn) onPeerHasAllPieces() {
+func (cn *PeerConn) onPeerHasAllPiecesNoTriggers() {
t := cn.t
if t.haveInfo() {
cn._peerPieces.Iterate(func(x uint32) bool {
t.addConnWithAllPieces(&cn.Peer)
cn.peerSentHaveAll = true
cn._peerPieces.Clear()
+}
+
+func (cn *PeerConn) onPeerHasAllPieces() {
+ cn.onPeerHasAllPiecesNoTriggers()
+ cn.peerHasAllPiecesTriggers()
+}
+
+func (cn *PeerConn) peerHasAllPiecesTriggers() {
if !cn.t._pendingPieces.IsEmpty() {
cn.updateRequests("Peer.onPeerHasAllPieces")
}
})
}
-func (c *PeerConn) setTorrent(t *Torrent) {
+func (c *Peer) setTorrent(t *Torrent) {
if c.t != nil {
panic("connection already associated with a torrent")
}
PieceState
}
-func (t *Torrent) publishPieceChange(piece pieceIndex) {
+func (t *Torrent) publishPieceStateChange(piece pieceIndex) {
t.cl._mu.Defer(func() {
cur := t.pieceState(piece)
p := &t.pieces[piece]
t.openNewConns()
}
-func (t *Torrent) piecePriorityChanged(piece pieceIndex, reason string) {
+func (t *Torrent) onPiecePendingTriggers(piece pieceIndex, reason string) {
if t._pendingPieces.Contains(uint32(piece)) {
t.iterPeers(func(c *Peer) {
// if c.requestState.Interested {
})
}
t.maybeNewConns()
- t.publishPieceChange(piece)
+ t.publishPieceStateChange(piece)
}
-func (t *Torrent) updatePiecePriority(piece pieceIndex, reason string) {
+func (t *Torrent) updatePiecePriorityNoTriggers(piece pieceIndex) (pendingChanged bool) {
if !t.closed.IsSet() {
// It would be possible to filter on pure-priority changes here to avoid churning the piece
// request order.
newPrio := p.uncachedPriority()
// t.logger.Printf("torrent %p: piece %d: uncached priority: %v", t, piece, newPrio)
if newPrio == PiecePriorityNone {
- if !t._pendingPieces.CheckedRemove(uint32(piece)) {
- return
- }
+ return t._pendingPieces.CheckedRemove(uint32(piece))
} else {
- if !t._pendingPieces.CheckedAdd(uint32(piece)) {
- return
- }
+ return t._pendingPieces.CheckedAdd(uint32(piece))
+ }
+}
+
+func (t *Torrent) updatePiecePriority(piece pieceIndex, reason string) {
+ if t.updatePiecePriorityNoTriggers(piece) {
+ t.onPiecePendingTriggers(piece, reason)
}
- t.piecePriorityChanged(piece, reason)
}
func (t *Torrent) updateAllPiecePriorities(reason string) {
t.logger.Printf("marked piece %v complete but still has dirtiers", piece)
}
if changed {
- log.Fstr("piece %d completion changed: %+v -> %+v", piece, cached, uncached).LogLevel(log.Debug, t.logger)
+ t.logger.Levelf(log.Debug, "piece %d completion changed: %+v -> %+v", piece, cached, uncached)
t.pieceCompletionChanged(piece, "Torrent.updatePieceCompletion")
}
return changed
// Reconcile bytes transferred before connection was associated with a
// torrent.
-func (t *Torrent) reconcileHandshakeStats(c *PeerConn) {
+func (t *Torrent) reconcileHandshakeStats(c *Peer) {
if c._stats != (ConnStats{
// Handshakes should only increment these fields:
BytesWritten: c._stats.BytesWritten,
}
p.marking = true
- t.publishPieceChange(piece)
+ t.publishPieceStateChange(piece)
defer func() {
p.marking = false
- t.publishPieceChange(piece)
+ t.publishPieceStateChange(piece)
}()
if passed {
p := t.piece(pi)
t.piecesQueuedForHash.Remove(bitmap.BitIndex(pi))
p.hashing = true
- t.publishPieceChange(pi)
+ t.publishPieceStateChange(pi)
t.updatePiecePriority(pi, "Torrent.tryCreatePieceHasher")
t.storageLock.RLock()
t.activePieceHashes++
return
}
t.piecesQueuedForHash.Add(bitmap.BitIndex(pieceIndex))
- t.publishPieceChange(pieceIndex)
+ t.publishPieceStateChange(pieceIndex)
t.updatePiecePriority(pieceIndex, "Torrent.queuePieceCheck")
t.tryCreateMorePieceHashers()
}