From a19a566064893ef9016a5b077e40eaf82ed82c5a Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Wed, 28 May 2025 00:29:39 +1000 Subject: [PATCH] Prevent concurrent piece marking --- piece.go | 2 ++ torrent.go | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/piece.go b/piece.go index 78f86b15..b7c78be1 100644 --- a/piece.go +++ b/piece.go @@ -53,6 +53,8 @@ type Piece struct { // This can include connections that have closed. dirtiers map[*Peer]struct{} + // Value to twiddle to detect races. + race byte // Currently being hashed. hashing bool // The piece state may have changed, and is being synchronized with storage. diff --git a/torrent.go b/torrent.go index a1dc80d5..c1769355 100644 --- a/torrent.go +++ b/torrent.go @@ -2508,9 +2508,10 @@ func (t *Torrent) pieceHashed(piece pieceIndex, passed bool, hashIoErr error) { if hasDirty { p.Flush() // You can be synchronous here! } + p.race++ err := p.Storage().MarkComplete() if err != nil { - t.logger.Levelf(log.Error, "error marking piece %v complete: %s", piece, err) + t.slogger().Error("error marking piece complete", "piece", piece, "err", err) } t.cl.lock() @@ -2673,7 +2674,8 @@ func (t *Torrent) startHash(pi pieceIndex) { func (t *Torrent) getPieceToHash() (_ g.Option[pieceIndex]) { for i := range t.piecesQueuedForHash.Iterate { - if t.piece(i).hashing { + p := t.piece(i) + if p.hashing || p.marking { continue } return g.Some(i) -- 2.51.0