From 8dc897d4a2163deaf89e8a84fc5188f55ed44f82 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Wed, 1 Dec 2021 18:24:17 +1100 Subject: [PATCH] Fix races using resources on Close --- client.go | 11 ++++------- tracker_scraper.go | 6 ++++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/client.go b/client.go index bd03da35..c491118b 100644 --- a/client.go +++ b/client.go @@ -422,26 +422,23 @@ func (cl *Client) eachDhtServer(f func(DhtServer)) { } } -// Stops the client. All connections to peers are closed and all activity will -// come to a halt. +// Stops the client. All connections to peers are closed and all activity will come to a halt. func (cl *Client) Close() (errs []error) { - cl.closed.Set() var closeGroup sync.WaitGroup // For concurrent cleanup to complete before returning cl.lock() - cl.event.Broadcast() for _, t := range cl.torrents { err := t.close(&closeGroup) if err != nil { errs = append(errs, err) } } - cl.unlock() - closeGroup.Wait() // defer is LIFO. We want to Wait() after cl.unlock() - cl.lock() for i := range cl.onClose { cl.onClose[len(cl.onClose)-1-i]() } + cl.closed.Set() cl.unlock() + cl.event.Broadcast() + closeGroup.Wait() // defer is LIFO. We want to Wait() after cl.unlock() return } diff --git a/tracker_scraper.go b/tracker_scraper.go index 9ec29589..93b3ebca 100644 --- a/tracker_scraper.go +++ b/tracker_scraper.go @@ -81,6 +81,12 @@ func (me *trackerScraper) getIp() (ip net.IP, err error) { err = errors.New("no ips") return } + me.t.cl.rLock() + defer me.t.cl.rUnlock() + if me.t.cl.closed.IsSet() { + err = errors.New("client is closed") + return + } for _, ip = range ips { if me.t.cl.ipIsBlocked(ip) { continue