]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Include closed connections in dirtiers
authorMatt Joiner <anacrolix@gmail.com>
Sat, 3 Feb 2018 01:08:16 +0000 (12:08 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Sat, 3 Feb 2018 01:08:16 +0000 (12:08 +1100)
connection.go
piece.go
torrent.go

index da18c5bc4dd4cd347fe5a45ae27da7c5d296e7cb..70afb2a85b27701045ae10f67ebd363b3c53b5c0 100644 (file)
@@ -1138,15 +1138,24 @@ func (c *connection) receiveChunk(msg *pp.Message) {
                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
index 8e89ba62c2dcfdf60bc1da9d8ae790d0f62175c0..1f094813007175849a77413e7f4414e97647aa65 100644 (file)
--- a/piece.go
+++ b/piece.go
@@ -59,6 +59,10 @@ type Piece struct {
        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 {
index a58d6b8f447f97040222279822d96333776fd0f8..2846d275485aa572da4157f9fada185848479002 100644 (file)
@@ -1623,15 +1623,14 @@ func (t *Torrent) verifyPiece(piece int) {
        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
 }