Skip to content

Commit

Permalink
eth/downloader: wait all fetcher goroutines to exit before terminating
Browse files Browse the repository at this point in the history
  • Loading branch information
rjl493456442 committed Apr 16, 2018
1 parent 60516c8 commit 1c20ec3
Showing 1 changed file with 8 additions and 9 deletions.
17 changes: 8 additions & 9 deletions eth/downloader/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand All @@ -516,6 +514,7 @@ func (d *Downloader) Cancel() {
}
}
d.cancelLock.Unlock()
d.cancelWg.Wait()
}

// Terminate interrupts the downloader, canceling all pending operations.
Expand Down

0 comments on commit 1c20ec3

Please sign in to comment.