]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Remove relevant webtorrent offers when closing Torrent
authorMatt Joiner <anacrolix@gmail.com>
Mon, 11 Jul 2022 05:02:24 +0000 (15:02 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 12 Jul 2022 05:49:58 +0000 (15:49 +1000)
(cherry picked from commit 73a0b5e4d2fe679aac31d87171537c70f91f46ee)

torrent.go
webtorrent/tracker-client.go
wstracker.go

index e53b6bef23f0c032aa6da9e08d212e27a8df7855..f18fc25231ac476c2c5e40124b8782e9c060c812 100644 (file)
@@ -61,6 +61,7 @@ type Torrent struct {
        userOnWriteChunkErr    func(error)
 
        closed   chansync.SetOnce
+       onClose  []func()
        infoHash metainfo.Hash
        pieces   []Piece
 
@@ -865,6 +866,9 @@ func (t *Torrent) close(wg *sync.WaitGroup) (err error) {
                err = errors.New("already closed")
                return
        }
+       for _, f := range t.onClose {
+               f()
+       }
        if t.storage != nil {
                wg.Add(1)
                go func() {
@@ -1614,11 +1618,10 @@ func (t *Torrent) runHandshookConnLoggingErr(pc *PeerConn) {
 }
 
 func (t *Torrent) startWebsocketAnnouncer(u url.URL) torrentTrackerAnnouncer {
-       wtc, release := t.cl.websocketTrackers.Get(u.String())
-       go func() {
-               <-t.closed.Done()
-               release()
-       }()
+       wtc, release := t.cl.websocketTrackers.Get(u.String(), t.infoHash)
+       // This needs to run before the Torrent is dropped from the Client, to prevent a new webtorrent.TrackerClient for
+       // the same info hash before the old one is cleaned up.
+       t.onClose = append(t.onClose, release)
        wst := websocketTrackerStatus{u, wtc}
        go func() {
                err := wtc.Announce(tracker.Started, t.infoHash)
index 1ec4b9d9c6f917200c2795665283a2ad8e286df9..3b8c6a6bbcdfb2a4cbe08a9a78fce75eace7cc7d 100644 (file)
@@ -187,6 +187,17 @@ func (tc *TrackerClient) closeUnusedOffers() {
        tc.outboundOffers = nil
 }
 
+func (tc *TrackerClient) CloseOffersForInfohash(infoHash [20]byte) {
+       tc.mu.Lock()
+       defer tc.mu.Unlock()
+       for key, offer := range tc.outboundOffers {
+               if offer.infoHash == infoHash {
+                       offer.peerConnection.Close()
+                       delete(tc.outboundOffers, key)
+               }
+       }
+}
+
 func (tc *TrackerClient) Announce(event tracker.AnnounceEvent, infoHash [20]byte) error {
        metrics.Add("outbound announces", 1)
        var randOfferId [20]byte
index 5338ceb913da7644b2d0db1623b8355799a0d38b..e8bde8c348c8a7ba36106ed1ae11e8f1f77d9702 100644 (file)
@@ -42,7 +42,7 @@ type websocketTrackers struct {
        Proxy              http.ProxyFunc
 }
 
-func (me *websocketTrackers) Get(url string) (*webtorrent.TrackerClient, func()) {
+func (me *websocketTrackers) Get(url string, infoHash [20]byte) (*webtorrent.TrackerClient, func()) {
        me.mu.Lock()
        defer me.mu.Unlock()
        value, ok := me.clients[url]
@@ -74,6 +74,7 @@ func (me *websocketTrackers) Get(url string) (*webtorrent.TrackerClient, func())
        return &value.TrackerClient, func() {
                me.mu.Lock()
                defer me.mu.Unlock()
+               value.TrackerClient.CloseOffersForInfohash(infoHash)
                value.refCount--
                if value.refCount == 0 {
                        value.TrackerClient.Close()