diff options
author | gary rong <garyrong0905@gmail.com> | 2018-04-16 16:37:48 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2018-04-16 16:37:48 +0800 |
commit | de2a7bb764c82dbaa80d37939c5862358174bc6e (patch) | |
tree | e2faf0ad5f342da3409f9d4cd64cdd08d451b11c /eth | |
parent | 6b2b328cdb51a99e2ce55f0bc22eeb9733c9ec30 (diff) | |
download | dexon-de2a7bb764c82dbaa80d37939c5862358174bc6e.tar.gz dexon-de2a7bb764c82dbaa80d37939c5862358174bc6e.tar.zst dexon-de2a7bb764c82dbaa80d37939c5862358174bc6e.zip |
eth/downloader: wait for all fetcher goroutines to exit before terminating (#16509)
Diffstat (limited to 'eth')
-rw-r--r-- | eth/downloader/downloader.go | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 9e4949899..8b181b8ad 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -135,9 +135,10 @@ type Downloader struct { stateCh chan dataPack // [eth/63] Channel receiving inbound node state data // Cancellation and termination - cancelPeer string // Identifier of the peer currently being used as the master (cancel on drop) - cancelCh chan struct{} // Channel to cancel mid-flight syncs - cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers + cancelPeer string // Identifier of the peer currently being used as the master (cancel on drop) + cancelCh chan struct{} // Channel to cancel mid-flight syncs + cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers + cancelWg sync.WaitGroup // Make sure all fetcher goroutines have exited. quitCh chan struct{} // Quit channel to signal termination quitLock sync.RWMutex // Lock to prevent double closes @@ -476,12 +477,11 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I // spawnSync runs d.process and all given fetcher functions to completion in // separate goroutines, returning the first error that appears. func (d *Downloader) spawnSync(fetchers []func() error) error { - var wg sync.WaitGroup errc := make(chan error, len(fetchers)) - wg.Add(len(fetchers)) + d.cancelWg.Add(len(fetchers)) for _, fn := range fetchers { fn := fn - go func() { defer wg.Done(); errc <- fn() }() + go func() { defer d.cancelWg.Done(); errc <- fn() }() } // Wait for the first error, then terminate the others. var err error @@ -498,12 +498,10 @@ func (d *Downloader) spawnSync(fetchers []func() error) error { } d.queue.Close() d.Cancel() - wg.Wait() return err } -// Cancel cancels all of the operations and resets the queue. It returns true -// if the cancel operation was completed. +// Cancel cancels all of the operations and resets the queue. func (d *Downloader) Cancel() { // Close the current cancel channel d.cancelLock.Lock() @@ -516,6 +514,7 @@ func (d *Downloader) Cancel() { } } d.cancelLock.Unlock() + d.cancelWg.Wait() } // Terminate interrupts the downloader, canceling all pending operations. |