From 9d91d111e9e6983c5e56738535095fb62bcb6cec Mon Sep 17 00:00:00 2001 From: Michael Street <5597260+MStreet3@users.noreply.github.com> Date: Wed, 26 Oct 2022 00:41:08 -0400 Subject: [PATCH] chain: resolve data race in sequential start stop test Resolve the data race in the sequential start stop unit test by ensuring that each goroutine launched in the Start method is properly accounted for in the client's waitgroup. Add a TODO to shutdown the rescan goroutine when the Stop method is called. --- chain/neutrino.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/chain/neutrino.go b/chain/neutrino.go index 646778bccf..7079e7d1a5 100644 --- a/chain/neutrino.go +++ b/chain/neutrino.go @@ -100,24 +100,36 @@ func (s *NeutrinoClient) Start() error { s.clientMtx.Lock() defer s.clientMtx.Unlock() if !s.started { + // Reset the client state. s.enqueueNotification = make(chan interface{}) s.dequeueNotification = make(chan interface{}) s.currentBlock = make(chan *waddrmgr.BlockStamp) s.quit = make(chan struct{}) s.started = true + + // Go place a ClientConnected notification onto the queue. s.wg.Add(1) go func() { + defer s.wg.Done() + select { case s.enqueueNotification <- ClientConnected{}: case <-s.quit: } }() + + // Go launch the notification handler. + s.wg.Add(1) go s.notificationHandler() } return nil } // Stop replicates the RPC client's Stop method. +// +// TODO(mstreet3): The Stop method does not cancel the long-running rescan +// goroutine. This is a memory leak. Stop should shutdown the rescan goroutine +// and reset the scanning state of the NeutrinoClient to false. func (s *NeutrinoClient) Stop() { s.clientMtx.Lock() defer s.clientMtx.Unlock()