connection.go | 17 +++++++++++++---- piece.go | 4 ++++ torrent.go | 11 +++++------ diff --git a/connection.go b/connection.go index da18c5bc4dd4cd347fe5a45ae27da7c5d296e7cb..70afb2a85b27701045ae10f67ebd363b3c53b5c0 100644 --- a/connection.go +++ b/connection.go @@ -1138,13 +1138,22 @@ t.queuePieceCheck(int(req.Index)) t.pendAllChunkSpecs(index) } + c.onDirtiedPiece(index) + + cl.event.Broadcast() + t.publishPieceChange(int(req.Index)) +} + +func (c *connection) onDirtiedPiece(piece int) { if c.peerTouchedPieces == nil { c.peerTouchedPieces = make(map[int]struct{}) } - c.peerTouchedPieces[index] = struct{}{} - - cl.event.Broadcast() - t.publishPieceChange(int(req.Index)) + c.peerTouchedPieces[piece] = struct{}{} + ds := &c.t.pieces[piece].dirtiers + if *ds == nil { + *ds = make(map[*connection]struct{}) + } + (*ds)[c] = struct{}{} } func (c *connection) uploadAllowed() bool { diff --git a/piece.go b/piece.go index 8e89ba62c2dcfdf60bc1da9d8ae790d0f62175c0..1f094813007175849a77413e7f4414e97647aa65 100644 --- a/piece.go +++ b/piece.go @@ -59,6 +59,10 @@ pendingWritesMutex sync.Mutex pendingWrites int noPendingWrites sync.Cond + + // Connections that have written data to this piece since its last check. + // This can include connections that have closed. + dirtiers map[*connection]struct{} } func (p *Piece) String() string { diff --git a/torrent.go b/torrent.go index a58d6b8f447f97040222279822d96333776fd0f8..2846d275485aa572da4157f9fada185848479002 100644 --- a/torrent.go +++ b/torrent.go @@ -1623,15 +1623,14 @@ t.pieceHashed(piece, sum == p.hash) t.publishPieceChange(piece) } -// Return the connections that touched a piece, and clear the entry while +// Return the connections that touched a piece, and clear the entries while // doing it. func (t *Torrent) reapPieceTouchers(piece int) (ret []*connection) { - for c := range t.conns { - if _, ok := c.peerTouchedPieces[piece]; ok { - ret = append(ret, c) - delete(c.peerTouchedPieces, piece) - } + for c := range t.pieces[piece].dirtiers { + delete(c.peerTouchedPieces, piece) + ret = append(ret, c) } + t.pieces[piece].dirtiers = nil return }