@@ -140,9 +140,10 @@ type Downloader struct {
140
140
stateCh chan dataPack // [eth/63] Channel receiving inbound node state data
141
141
142
142
// Cancellation and termination
143
- cancelPeer string // Identifier of the peer currently being used as the master (cancel on drop)
144
- cancelCh chan struct {} // Channel to cancel mid-flight syncs
145
- cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers
143
+ cancelPeer string // Identifier of the peer currently being used as the master (cancel on drop)
144
+ cancelCh chan struct {} // Channel to cancel mid-flight syncs
145
+ cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers
146
+ cancelWg sync.WaitGroup // Make sure all fetcher goroutines have exited.
146
147
147
148
quitCh chan struct {} // Quit channel to signal termination
148
149
quitLock sync.Mutex // Lock to prevent double closes
@@ -312,7 +313,7 @@ func (d *Downloader) UnregisterPeer(id string) error {
312
313
d .cancelLock .RUnlock ()
313
314
314
315
if master {
315
- d .Cancel ()
316
+ d .cancel ()
316
317
}
317
318
return nil
318
319
}
@@ -483,12 +484,11 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
483
484
// spawnSync runs d.process and all given fetcher functions to completion in
484
485
// separate goroutines, returning the first error that appears.
485
486
func (d * Downloader ) spawnSync (fetchers []func () error ) error {
486
- var wg sync.WaitGroup
487
487
errc := make (chan error , len (fetchers ))
488
- wg .Add (len (fetchers ))
488
+ d . cancelWg .Add (len (fetchers ))
489
489
for _ , fn := range fetchers {
490
490
fn := fn
491
- go func () { defer wg .Done (); errc <- fn () }()
491
+ go func () { defer d . cancelWg .Done (); errc <- fn () }()
492
492
}
493
493
// Wait for the first error, then terminate the others.
494
494
var err error
@@ -505,16 +505,16 @@ func (d *Downloader) spawnSync(fetchers []func() error) error {
505
505
}
506
506
d .queue .Close ()
507
507
d .Cancel ()
508
- wg .Wait ()
509
508
if err == errEnoughBlock {
510
509
return nil
511
510
}
512
511
return err
513
512
}
514
513
515
- // Cancel cancels all of the operations and resets the queue. It returns true
516
- // if the cancel operation was completed.
517
- func (d * Downloader ) Cancel () {
514
+ // cancel aborts all of the operations and resets the queue. However, cancel does
515
+ // not wait for the running download goroutines to finish. This method should be
516
+ // used when cancelling the downloads from inside the downloader.
517
+ func (d * Downloader ) cancel () {
518
518
// Close the current cancel channel
519
519
d .cancelLock .Lock ()
520
520
if d .cancelCh != nil {
@@ -528,6 +528,13 @@ func (d *Downloader) Cancel() {
528
528
d .cancelLock .Unlock ()
529
529
}
530
530
531
+ // Cancel aborts all of the operations and waits for all download goroutines to
532
+ // finish before returning.
533
+ func (d * Downloader ) Cancel () {
534
+ d .cancel ()
535
+ d .cancelWg .Wait ()
536
+ }
537
+
531
538
// Terminate interrupts the downloader, canceling all pending operations.
532
539
// The downloader cannot be reused after calling Terminate.
533
540
func (d * Downloader ) Terminate () {
0 commit comments