From: Matt Joiner Date: Tue, 5 Aug 2025 09:59:32 +0000 (+1000) Subject: Ensure Torrent.pieceCompletionChanged always runs on piece init X-Git-Tag: v1.59.0~2^2~60 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=a67a07991d0282bf0216f9a3be2ed3a90e4312f0;p=btrtrc.git Ensure Torrent.pieceCompletionChanged always runs on piece init --- diff --git a/torrent.go b/torrent.go index 9d99d1ea..f1c334a5 100644 --- a/torrent.go +++ b/torrent.go @@ -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.