diff --git a/peerconn.go b/peerconn.go index cf9ace9d..de82cf3b 100644 --- a/peerconn.go +++ b/peerconn.go @@ -312,6 +312,9 @@ func (cn *Peer) downloadRate() float64 { func (cn *Peer) writeStatus(w io.Writer, t *Torrent) { // \t isn't preserved in
blocks? + if cn.closed.IsSet() { + fmt.Fprint(w, "CLOSED: ") + } fmt.Fprintln(w, cn.connStatusString()) fmt.Fprintf(w, " last msg: %s, connected: %s, last helpful: %s, itime: %s, etime: %s\n", eventAgeString(cn.lastMessageReceived), @@ -787,11 +790,14 @@ func (cn *Peer) shouldRequestWithoutBias() bool { return cn.t.requestStrategy.shouldRequestWithoutBias(cn.requestStrategyConnection()) } -func (cn *Peer) iterPendingPieces(f func(pieceIndex) bool) bool { +func (cn *Peer) iterPendingPieces(f func(pieceIndex) bool) { if !cn.t.haveInfo() { - return false + return } - return cn.t.requestStrategy.iterPendingPieces(cn, f) + if cn.closed.IsSet() { + return + } + cn.t.requestStrategy.iterPendingPieces(cn, f) } func (cn *Peer) iterPendingPiecesUntyped(f iter.Callback) { cn.iterPendingPieces(func(i pieceIndex) bool { return f(i) }) diff --git a/webseed-peer.go b/webseed-peer.go index 72c9173d..e436f8aa 100644 --- a/webseed-peer.go +++ b/webseed-peer.go @@ -1,6 +1,8 @@ package torrent import ( + "context" + "errors" "fmt" "strings" "sync" @@ -10,7 +12,6 @@ import ( pp "github.com/anacrolix/torrent/peer_protocol" "github.com/anacrolix/torrent/segments" "github.com/anacrolix/torrent/webseed" - "github.com/pkg/errors" ) type webseedPeer struct { @@ -64,9 +65,11 @@ func (ws *webseedPeer) request(r Request) bool { func (ws *webseedPeer) doRequest(r Request) { webseedRequest := ws.client.NewRequest(ws.intoSpec(r)) ws.activeRequests[r] = webseedRequest - ws.requesterCond.L.Unlock() - ws.requestResultHandler(r, webseedRequest) - ws.requesterCond.L.Lock() + func() { + ws.requesterCond.L.Unlock() + defer ws.requesterCond.L.Lock() + ws.requestResultHandler(r, webseedRequest) + }() delete(ws.activeRequests, r) } @@ -99,6 +102,10 @@ func (ws *webseedPeer) updateRequests() { } func (ws *webseedPeer) onClose() { + ws.peer.logger.Print("closing") + for _, r := range ws.activeRequests { + r.Cancel() + } ws.requesterCond.Broadcast() } @@ -107,12 +114,14 @@ func (ws *webseedPeer) requestResultHandler(r Request, webseedRequest webseed.Re ws.peer.t.cl.lock() defer ws.peer.t.cl.unlock() if result.Err != nil { - ws.peer.logger.Printf("Request %v rejected: %v", r, result.Err) + if !errors.Is(result.Err, context.Canceled) { + ws.peer.logger.Printf("Request %v rejected: %v", r, result.Err) + } // Always close for now. We need to filter out temporary errors, but this is a nightmare in // Go. Currently a bad webseed URL can starve out the good ones due to the chunk selection // algorithm. const closeOnAllErrors = false - if closeOnAllErrors || strings.Contains(errors.Cause(result.Err).Error(), "unsupported protocol scheme") { + if closeOnAllErrors || strings.Contains(result.Err.Error(), "unsupported protocol scheme") { ws.peer.close() } else { ws.peer.remoteRejectedRequest(r)