]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Ensure Torrent.pieceCompletionChanged always runs on piece init
authorMatt Joiner <anacrolix@gmail.com>
Tue, 5 Aug 2025 09:59:32 +0000 (19:59 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 5 Aug 2025 09:59:32 +0000 (19:59 +1000)
torrent.go

index 9d99d1eac15f8f90e95e9c574e4ab9dd8bfe5d35..f1c334a51f9919c8b842b83292063fe035bd1209 100644 (file)
@@ -577,6 +577,8 @@ func (t *Torrent) onSetInfo() {
                }
                p.relativeAvailability = t.selectivePieceAvailabilityFromPeers(i)
                t.addRequestOrderPiece(i)
+               t.setPieceCompletionFromStorage(i)
+               t.afterSetPieceCompletion(i, true)
                t.updatePieceCompletion(i)
                t.queueInitialPieceCheck(i)
        }
@@ -1716,8 +1718,8 @@ func (t *Torrent) openNewConns() (initiated int) {
        return
 }
 
-// Pulls piece completion state from storage and performs any state updates if it changes.
-func (t *Torrent) updatePieceCompletion(piece pieceIndex) bool {
+// Sets the cached piece completion directly from storage.
+func (t *Torrent) setPieceCompletionFromStorage(piece pieceIndex) bool {
        p := t.piece(piece)
        uncached := t.pieceCompleteUncached(piece)
        if uncached.Err != nil {
@@ -1728,29 +1730,39 @@ func (t *Torrent) updatePieceCompletion(piece pieceIndex) bool {
        // errors.
        cached := p.completion()
        changed := cached != uncached
-       complete := uncached.Ok && uncached.Complete
        p.storageCompletionOk = uncached.Ok
        x := uint32(piece)
-       if complete {
+       if uncached.Complete {
                t._completedPieces.Add(x)
-               t.openNewConns()
        } else {
                t._completedPieces.Remove(x)
        }
+       return changed
+}
+
+// Pulls piece completion state from storage and performs any state updates if it changes.
+func (t *Torrent) updatePieceCompletion(piece pieceIndex) bool {
+       changed := t.setPieceCompletionFromStorage(piece)
+       t.afterSetPieceCompletion(piece, changed)
+       return changed
+}
+
+// Pulls piece completion state from storage and performs any state updates if it changes.
+func (t *Torrent) afterSetPieceCompletion(piece pieceIndex, changed bool) {
+       p := t.piece(piece)
+       cmpl := p.completion()
+       complete := cmpl.Ok && cmpl.Complete
+       if complete {
+               t.openNewConns()
+       }
        p.t.updatePieceRequestOrderPiece(piece)
        t.updateComplete()
        if complete && len(p.dirtiers) != 0 {
                t.logger.Printf("marked piece %v complete but still has dirtiers", piece)
        }
        if changed {
-               //slog.Debug(
-               //      "piece completion changed",
-               //      slog.Int("piece", piece),
-               //      slog.Any("from", cached),
-               //      slog.Any("to", uncached))
                t.pieceCompletionChanged(piece, "Torrent.updatePieceCompletion")
        }
-       return changed
 }
 
 // Non-blocking read. Client lock is not required.