client.go | 2 +- peer-impl.go | 2 ++ peerconn.go | 13 +++++++------ torrent.go | 3 ++- webseed-peer.go | 8 +++++++- diff --git a/client.go b/client.go index 72013b99bf13ecbe34f400341ce41033114021b8..142213c08934cfc66c70d07df57b37777f060709 100644 --- a/client.go +++ b/client.go @@ -983,7 +983,7 @@ defer c.locker().Unlock() if c.needRequestUpdate != "" { return } - if c.actualRequestState.Requests.IsEmpty() { + if c.isLowOnRequests() { // If there are no outstanding requests, then a request update should have already run. return } diff --git a/peer-impl.go b/peer-impl.go index 4dbc6b4c08046832804203eb80a638d944e28619..b5cf028ecd98b3a75d7d927b31c165b735ade44f 100644 --- a/peer-impl.go +++ b/peer-impl.go @@ -10,6 +10,8 @@ // legacy PeerConn methods. type peerImpl interface { // Trigger the actual request state to get updated handleUpdateRequests() + // Whether the outstanding local request cardinality is low enough to warrant an update. + isLowOnRequests() bool writeInterested(interested bool) bool // Neither of these return buffer room anymore, because they're currently both posted. There's diff --git a/peerconn.go b/peerconn.go index a9d0baad2696e0fc5e0161b2a9dc723bc162dcea..005c6b7d93f1c497b703f0a514f61861fd7a64cb 100644 --- a/peerconn.go +++ b/peerconn.go @@ -630,7 +630,7 @@ } else { if !me.deleteRequest(r) { panic("request not existing should have been guarded") } - if me.actualRequestState.Requests.IsEmpty() { + if me.isLowOnRequests() { me.updateRequests("Peer.cancel") } } @@ -1195,7 +1195,7 @@ } func (c *Peer) remoteRejectedRequest(r RequestIndex) { if c.deleteRequest(r) { - if c.actualRequestState.Requests.IsEmpty() { + if c.isLowOnRequests() { c.updateRequests("Peer.remoteRejectedRequest") } c.decExpectedChunkReceive(r) @@ -1334,7 +1334,7 @@ deletedRequest = true if !c.peerChoking { c._chunksReceivedWhileExpecting++ } - if c.actualRequestState.Requests.IsEmpty() { + if c.isLowOnRequests() { c.updateRequests("Peer.receiveChunk deleted request") } } else { @@ -1542,9 +1542,6 @@ }) if !c.actualRequestState.Requests.IsEmpty() { panic(c.actualRequestState.Requests.GetCardinality()) } - // for c := range c.t.conns { - // c.tickleWriter() - // } } // This is called when something has changed that should wake the writer, such as putting stuff into @@ -1671,3 +1668,7 @@ func (p *Peer) TryAsPeerConn() (*PeerConn, bool) { pc, ok := p.peerImpl.(*PeerConn) return pc, ok } + +func (pc *PeerConn) isLowOnRequests() bool { + return pc.actualRequestState.Requests.IsEmpty() +} diff --git a/torrent.go b/torrent.go index 9227734271db72514e0aa9b592dc2bd6b0460ee2..f594c9f625c255a1a22b1d77b6b5db030ccdb7e6 100644 --- a/torrent.go +++ b/torrent.go @@ -1085,7 +1085,7 @@ t.iterPeers(func(c *Peer) { if c.actualRequestState.Interested { return } - if !c.actualRequestState.Requests.IsEmpty() { + if !c.isLowOnRequests() { return } if !c.peerHasPiece(piece) { @@ -2225,6 +2225,7 @@ HttpClient: WebseedHttpClient, Url: url, }, activeRequests: make(map[Request]webseed.Request, maxRequests), + maxRequests: maxRequests, } ws.peer.initUpdateRequestsTimer() ws.requesterCond.L = t.cl.locker() diff --git a/webseed-peer.go b/webseed-peer.go index 68fbc3e7458d707c11851ee6935d848443d5756e..fb981585be2b6925311e34e58e54db649f3285a7 100644 --- a/webseed-peer.go +++ b/webseed-peer.go @@ -21,6 +21,8 @@ client webseed.Client activeRequests map[Request]webseed.Request requesterCond sync.Cond peer Peer + // Number of requester routines. + maxRequests int } var _ peerImpl = (*webseedPeer)(nil) @@ -49,7 +51,7 @@ active.Cancel() if !ws.peer.deleteRequest(r) { panic("cancelled webseed request should exist") } - if ws.peer.actualRequestState.Requests.IsEmpty() { + if ws.peer.isLowOnRequests() { ws.peer.updateRequests("webseedPeer._cancel") } } @@ -158,3 +160,7 @@ panic(err) } } } + +func (me *webseedPeer) isLowOnRequests() bool { + return me.peer.actualRequestState.Requests.GetCardinality() < uint64(me.maxRequests) +}