]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Prevent concurrent piece marking
authorMatt Joiner <anacrolix@gmail.com>
Tue, 27 May 2025 14:29:39 +0000 (00:29 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 27 May 2025 14:29:39 +0000 (00:29 +1000)
piece.go
torrent.go

index 78f86b15fbb5bbe08c299061f695e05171aa026a..b7c78be15b149b14a2f3008af664432899d9dc93 100644 (file)
--- 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.
index a1dc80d51dd1f59a7dbe882fb4da2236e7b3b0aa..c1769355dc0e9a0cfeef0ce3f3a53fc86ac7cc88 100644 (file)
@@ -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)