panic("requesting piece peer doesn't have")
}
cn.requests[r] = struct{}{}
+ cn.t.pendingRequests[r]++
return mw(pp.Message{
Type: pp.Request,
Index: r.Index,
switch msg.Type {
case pp.Choke:
c.PeerChoked = true
- c.requests = nil
+ c.deleteAllRequests()
// We can then reset our interest.
c.updateRequests()
case pp.Reject:
return false
}
delete(c.requests, r)
+ c.t.pendingRequests[r]--
return true
}
+func (c *connection) deleteAllRequests() {
+ for r := range c.requests {
+ c.deleteRequest(r)
+ }
+ // for c := range c.t.conns {
+ // c.tickleWriter()
+ // }
+}
+
func (c *connection) tickleWriter() {
c.writerCond.Broadcast()
}
connPieceInclinationPool sync.Pool
// Torrent-level statistics.
stats TorrentStats
+
+ pendingRequests map[request]int
}
// Returns a channel that is closed when the Torrent is closed.
t.cl.event.Broadcast()
t.gotMetainfo.Set()
t.updateWantPeersEvent()
+ t.pendingRequests = make(map[request]int)
}
// Called when metadata for a torrent becomes available.
func (t *Torrent) deleteConnection(c *connection) (ret bool) {
_, ret = t.conns[c]
delete(t.conns, c)
+ c.deleteAllRequests()
+ if len(t.conns) == 0 {
+ t.assertNoPendingRequests()
+ }
return
}
+func (t *Torrent) assertNoPendingRequests() {
+ for _, num := range t.pendingRequests {
+ if num != 0 {
+ panic(num)
+ }
+ }
+}
+
func (t *Torrent) dropConnection(c *connection) {
t.cl.event.Broadcast()
c.Close()