]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Fix piece getting queued for hash multiple times
authorMatt Joiner <anacrolix@gmail.com>
Thu, 5 Nov 2020 21:39:56 +0000 (08:39 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 5 Nov 2020 21:39:56 +0000 (08:39 +1100)
Pieces could get queued for hash multiple times when we receive chunks if the piece starts getting hashed before we're done writing all the chunks out. This was only found because piece hashing currently only checks the incomplete data, which is missing after the first piece hash passes, the data is marked complete, then the subsequently queued hash has nothing to read.

peerconn.go
piece.go

index d975af4f42675c4396922ce0a7d195b73357f6f1..48acbc111f111386b06c76254af616043c430f54 100644 (file)
@@ -1354,7 +1354,8 @@ func (c *peer) receiveChunk(msg *pp.Message) error {
 
        c.onDirtiedPiece(pieceIndex(req.Index))
 
-       if t.pieceAllDirty(pieceIndex(req.Index)) {
+       // We need to ensure the piece is only queued once, so only the last chunk writer gets this job.
+       if t.pieceAllDirty(pieceIndex(req.Index)) && piece.pendingWrites == 0 {
                t.queuePieceCheck(pieceIndex(req.Index))
                // We don't pend all chunks here anymore because we don't want code dependent on the dirty
                // chunk status (such as the haveChunk call above) to have to check all the various other
index 2e6a4259a109b7579ad37370c71bccebf6e7d6cc..56dedec6d044c954fcf7364908e8bef9dfc1a8bb 100644 (file)
--- a/piece.go
+++ b/piece.go
@@ -55,6 +55,7 @@ type Piece struct {
        publicPieceState PieceState
        priority         piecePriority
 
+       // This can be locked when the Client lock is taken, but probably not vice versa.
        pendingWritesMutex sync.Mutex
        pendingWrites      int
        noPendingWrites    sync.Cond