t.pendAllChunkSpecs(index)
}
- if c.peerTouchedPieces == nil {
- c.peerTouchedPieces = make(map[int]struct{})
- }
- c.peerTouchedPieces[index] = struct{}{}
+ 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[piece] = struct{}{}
+ ds := &c.t.pieces[piece].dirtiers
+ if *ds == nil {
+ *ds = make(map[*connection]struct{})
+ }
+ (*ds)[c] = struct{}{}
+}
+
func (c *connection) uploadAllowed() bool {
if c.t.cl.config.NoUpload {
return false
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 {
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
}