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
|
return
|
||||||
}
|
}
|
||||||
err = t.close(wg)
|
err = t.close(wg)
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
delete(cl.torrents, infoHash)
|
delete(cl.torrents, infoHash)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,12 +245,20 @@ func (r *reader) readOnceAt(ctx context.Context, b []byte, pos int64) (n int, er
|
||||||
err = nil
|
err = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if r.t.closed.IsSet() {
|
||||||
|
err = fmt.Errorf("reading from closed torrent: %w", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
r.t.cl.lock()
|
r.t.cl.lock()
|
||||||
// I think there's a panic here caused by the Client being closed before obtaining this
|
// I think there's a panic here caused by the Client being closed before obtaining this
|
||||||
// lock. TestDropTorrentWithMmapStorageWhileHashing seems to tickle occasionally in CI.
|
// lock. TestDropTorrentWithMmapStorageWhileHashing seems to tickle occasionally in CI.
|
||||||
func() {
|
func() {
|
||||||
// Just add exceptions already.
|
// Just add exceptions already.
|
||||||
defer r.t.cl.unlock()
|
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
|
// TODO: Just reset pieces in the readahead window. This might help
|
||||||
// prevent thrashing with small caches and file and piece priorities.
|
// 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",
|
r.log(log.Fstr("error reading torrent %s piece %d offset %d, %d bytes: %v",
|
||||||
|
|
|
@ -850,7 +850,10 @@ func (t *Torrent) numPiecesCompleted() (num pieceIndex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Torrent) close(wg *sync.WaitGroup) (err error) {
|
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 {
|
if t.storage != nil {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
|
Loading…
Reference in New Issue