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)