peerconn.go | 3 ++- piece.go | 1 + diff --git a/peerconn.go b/peerconn.go index d975af4f42675c4396922ce0a7d195b73357f6f1..48acbc111f111386b06c76254af616043c430f54 100644 --- a/peerconn.go +++ b/peerconn.go @@ -1354,7 +1354,8 @@ } 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 diff --git a/piece.go b/piece.go index 2e6a4259a109b7579ad37370c71bccebf6e7d6cc..56dedec6d044c954fcf7364908e8bef9dfc1a8bb 100644 --- a/piece.go +++ b/piece.go @@ -55,6 +55,7 @@ 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