var msg pp.Message
err := decoder.Decode(&msg)
me.mu.Lock()
+ if c.closed {
+ return nil
+ }
if err != nil {
if me.stopped() || err == io.EOF {
return nil
log.Printf("received unexpected cancel: %v", req)
}
case pp.Bitfield:
- if len(msg.Bitfield) < len(t.Pieces) {
+ if len(msg.Bitfield) < t.NumPieces() {
err = errors.New("received invalid bitfield")
break
}
err = errors.New("received unexpected bitfield")
break
}
- c.PeerPieces = msg.Bitfield[:len(t.Pieces)]
+ c.PeerPieces = msg.Bitfield[:len(t.NumPieces())]
for index, has := range c.PeerPieces {
if has {
me.peerGotPiece(t, c, index)
}
func (me *Client) addConnection(t *torrent, c *connection) bool {
+ if me.stopped() {
+ return false
+ }
for _, c0 := range t.Conns {
if c.PeerId == c0.PeerId {
// Already connected to a client with that ID.
// Then finish off incomplete pieces in order of bytes remaining.
for _, heatThreshold := range []int{0, 4, 100} {
for _, pieceIndex := range ppbs {
- for chunkSpec := range t.Pieces[pieceIndex].PendingChunkSpecs {
+ for _, chunkSpec := range t.Pieces[pieceIndex].shuffledPendingChunkSpecs() {
r := request{pieceIndex, chunkSpec}
if th[r] > heatThreshold {
continue
}
readaheadPieces := (me.Readahead + t.UsualPieceSize() - 1) / t.UsualPieceSize()
for i := t.lastReadPiece; i < t.lastReadPiece+readaheadPieces && i < t.NumPieces(); i++ {
- for cs := range t.Pieces[i].PendingChunkSpecs {
+ for _, cs := range t.Pieces[i].shuffledPendingChunkSpecs() {
if !c.Request(request{pp.Integer(i), cs}) {
return
}
// Then finish off incomplete pieces in order of bytes remaining.
for _, index := range t.piecesByPendingBytes() {
// Stop when we're onto untouched pieces.
- if t.PieceNumPendingBytes(index) == t.PieceLength(index) {
+ if !t.PiecePartiallyDownloaded(int(index)) {
break
}
// Request chunks in random order to reduce overlap with other
func (me *Client) replenishConnRequests(t *torrent, c *connection) {
me.DownloadStrategy.FillRequests(t, c)
+ me.assertRequestHeat()
if len(c.Requests) == 0 {
c.SetInterested(false)
}
p.EverHashed = true
if correct {
p.PendingChunkSpecs = nil
- log.Printf("%s: got piece %d, (%d/%d)", t, piece, t.NumPiecesCompleted(), t.NumPieces())
+ // log.Printf("%s: got piece %d, (%d/%d)", t, piece, t.NumPiecesCompleted(), t.NumPieces())
var next *list.Element
for e := t.Priorities.Front(); e != nil; e = next {
next = e.Next()