upnpMappings []*upnpMapping
- webseedRequestTimer *time.Timer
- webseedUpdateReason updateRequestReason
+ webseedRequestTimer *time.Timer
+ webseedUpdateReason updateRequestReason
+ activeWebseedRequests map[webseedUniqueRequestKey]*webseedRequest
activePieceHashers int
}
t.pieceStateChanges.Close()
t.updateWantPeersEvent()
g.MustDelete(t.cl.torrents, t)
+ // This doesn't work yet because requests remove themselves after they close, and we don't
+ // remove them synchronously.
+ if false {
+ if len(t.cl.torrents) == 0 {
+ panicif.NotZero(len(t.cl.activeWebseedRequests))
+ }
+ }
return
}
if t.cl.config.DisableWebseeds {
return false
}
- if _, ok := t.webSeeds[webseedUrlKey(unique.Make(url))]; ok {
+ urlKey := webseedUrlKey(unique.Make(url))
+ if _, ok := t.webSeeds[urlKey]; ok {
return false
}
// I don't think Go http supports pipelining requests. However, we can have more ready to go
ResponseBodyRateLimiter: t.cl.config.DownloadRateLimiter,
},
hostKey: t.deriveWebSeedHostKey(url),
+ url: urlKey,
}
ws.peer.initClosedCtx()
for _, opt := range opts {
if t.haveInfo() {
ws.onGotInfo(t.info)
}
- t.webSeeds[webseedUrlKey(unique.Make(url))] = &ws
+ t.webSeeds[urlKey] = &ws
ws.peer.onNeedUpdateRequests("Torrent.addWebSeed")
return true
}
locker sync.Locker
lastUnhandledErr time.Time
hostKey webseedHostKeyHandle
+ // We need this to look ourselves up in the Client.activeWebseedRequests map.
+ url webseedUrlKey
}
func (*webseedPeer) allConnStatsImplField(stats *AllConnStats) *ConnStats {
ws.peer.t.cl.dumpCurrentWebseedRequests()
}
ws.activeRequests[&wsReq] = struct{}{}
+ t := ws.peer.t
+ cl := t.cl
+ g.MakeMapIfNil(&cl.activeWebseedRequests)
+ g.MapMustAssignNew(cl.activeWebseedRequests, ws.getRequestKey(&wsReq), &wsReq)
ws.peer.updateExpectingChunks()
panicif.Zero(ws.hostKey)
ws.peer.t.cl.numWebSeedRequests[ws.hostKey]++
go ws.runRequest(&wsReq)
}
+func (me *webseedPeer) getRequestKey(wr *webseedRequest) webseedUniqueRequestKey {
+ // This is used to find the request in the Client's active requests map.
+ return webseedUniqueRequestKey{
+ url: me.url,
+ t: me.peer.t,
+ sliceIndex: me.peer.t.requestIndexToWebseedSliceIndex(wr.begin),
+ }
+}
+
func (me *webseedPeer) hasOverlappingRequests(begin, end RequestIndex) bool {
for req := range me.activeRequests {
if req.cancelled.Load() {
func (ws *webseedPeer) deleteActiveRequest(wr *webseedRequest) {
g.MustDelete(ws.activeRequests, wr)
- ws.peer.t.cl.numWebSeedRequests[ws.hostKey]--
+ cl := ws.peer.cl
+ cl.numWebSeedRequests[ws.hostKey]--
+ g.MustDelete(cl.activeWebseedRequests, ws.getRequestKey(wr))
ws.peer.updateExpectingChunks()
}