client.go | 3 --- reader.go | 8 ++++++++ torrent.go | 7 +++++-- diff --git a/client.go b/client.go index d5f96c0ee33d7b801065902d8d7f10eedc9aecdb..ee8261f378d580b56c5fdef1c3c6222cdfabe6b6 100644 --- a/client.go +++ b/client.go @@ -1352,9 +1352,6 @@ err = fmt.Errorf("no such torrent") return } err = t.close(wg) - if err != nil { - panic(err) - } delete(cl.torrents, infoHash) return } diff --git a/reader.go b/reader.go index c2f3de89bcdef01765b4a201ca0c984abaf536fd..9670ff094a8a2ba77f2fd56bbd503757f113fd6b 100644 --- a/reader.go +++ b/reader.go @@ -245,12 +245,20 @@ if n != 0 { err = nil return } + if r.t.closed.IsSet() { + err = fmt.Errorf("reading from closed torrent: %w", err) + return + } r.t.cl.lock() // I think there's a panic here caused by the Client being closed before obtaining this // lock. TestDropTorrentWithMmapStorageWhileHashing seems to tickle occasionally in CI. func() { // Just add exceptions already. defer r.t.cl.unlock() + if r.t.closed.IsSet() { + // Can't update because Torrent's piece order is removed from Client. + return + } // TODO: Just reset pieces in the readahead window. This might help // prevent thrashing with small caches and file and piece priorities. r.log(log.Fstr("error reading torrent %s piece %d offset %d, %d bytes: %v", diff --git a/torrent.go b/torrent.go index 7e6ec24cc2c8c76ac507e3e3adce34c3a5e14eec..6a75eff3452209df500d4bb01c8d1a4dd06d14ac 100644 --- a/torrent.go +++ b/torrent.go @@ -153,7 +153,7 @@ // Torrent sources in use keyed by the source string. activeSources sync.Map sourcesLogger log.Logger - + smartBanCache smartBanCache } @@ -850,7 +850,10 @@ return pieceIndex(t._completedPieces.GetCardinality()) } func (t *Torrent) close(wg *sync.WaitGroup) (err error) { - t.closed.Set() + if !t.closed.Set() { + err = errors.New("already closed") + return + } if t.storage != nil { wg.Add(1) go func() {