From e178f99f35a6d3c55352cabef55c852ff966f80e Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 25 Oct 2021 16:15:42 +1100 Subject: [PATCH] Fix race running and closing webtorrent tracker clients --- webtorrent/tracker_client.go | 11 ++++++++++- wstracker.go | 5 ++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/webtorrent/tracker_client.go b/webtorrent/tracker_client.go index 7972fb08..e6908c74 100644 --- a/webtorrent/tracker_client.go +++ b/webtorrent/tracker_client.go @@ -106,9 +106,18 @@ func (tc *TrackerClient) doWebsocket() error { return err } -func (tc *TrackerClient) Run() error { +// Finishes initialization and spawns the run routine, calling onStop when it completes with the +// result. We don't let the caller just spawn the runner directly, since then we can race against +// .Close to finish initialization. +func (tc *TrackerClient) Start(onStop func(error)) { tc.pingTicker = time.NewTicker(60 * time.Second) tc.cond.L = &tc.mu + go func() { + onStop(tc.run()) + }() +} + +func (tc *TrackerClient) run() error { tc.mu.Lock() for !tc.closed { tc.mu.Unlock() diff --git a/wstracker.go b/wstracker.go index 4e83ca5f..f93f784a 100644 --- a/wstracker.go +++ b/wstracker.go @@ -55,12 +55,11 @@ func (me *websocketTrackers) Get(url string) (*webtorrent.TrackerClient, func()) }), }, } - go func() { - err := value.TrackerClient.Run() + value.TrackerClient.Start(func(err error) { if err != nil { me.Logger.Printf("error running tracker client for %q: %v", url, err) } - }() + }) if me.clients == nil { me.clients = make(map[string]*refCountedWebtorrentTrackerClient) } -- 2.48.1