Fix races around Reader and Torrent.Drop when Torrent is closed
This commit is contained in:
parent
7671a55a5c
commit
d8611ecf2d
|
@ -1352,9 +1352,6 @@ func (cl *Client) dropTorrent(infoHash metainfo.Hash, wg *sync.WaitGroup) (err e
|
|||
return
|
||||
}
|
||||
err = t.close(wg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
delete(cl.torrents, infoHash)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -245,12 +245,20 @@ func (r *reader) readOnceAt(ctx context.Context, b []byte, pos int64) (n int, er
|
|||
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",
|
||||
|
|
|
@ -153,7 +153,7 @@ type Torrent struct {
|
|||
// Torrent sources in use keyed by the source string.
|
||||
activeSources sync.Map
|
||||
sourcesLogger log.Logger
|
||||
|
||||
|
||||
smartBanCache smartBanCache
|
||||
}
|
||||
|
||||
|
@ -850,7 +850,10 @@ func (t *Torrent) numPiecesCompleted() (num pieceIndex) {
|
|||
}
|
||||
|
||||
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() {
|
||||
|
|
Loading…
Reference in New Issue