Browse Source

Merge pull request #2637 from karalabe/downloader-always-cancel

eth/downloader: ensure cancel channel is closed post sync
Péter Szilágyi 9 years ago
parent
commit
16a23ff740
2 changed files with 13 additions and 1 deletions
  1. 2 0
      eth/downloader/downloader.go
  2. 11 1
      eth/downloader/downloader_test.go

+ 2 - 0
eth/downloader/downloader.go

@@ -326,6 +326,8 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode
 	d.cancelCh = make(chan struct{})
 	d.cancelLock.Unlock()
 
+	defer d.cancel() // No matter what, we can't leave the cancel channel open
+
 	// Set the requested sync mode, unless it's forbidden
 	d.mode = mode
 	if d.mode == FastSync && d.noFast {

+ 11 - 1
eth/downloader/downloader_test.go

@@ -188,7 +188,17 @@ func (dl *downloadTester) sync(id string, td *big.Int, mode SyncMode) error {
 		}
 	}
 	dl.lock.RUnlock()
-	return dl.downloader.synchronise(id, hash, td, mode)
+
+	// Synchronise with the chosen peer and ensure proper cleanup afterwards
+	err := dl.downloader.synchronise(id, hash, td, mode)
+	select {
+	case <-dl.downloader.cancelCh:
+		// Ok, downloader fully cancelled after sync cycle
+	default:
+		// Downloader is still accepting packets, can block a peer up
+		panic("downloader active post sync cycle") // panic will be caught by tester
+	}
+	return err
 }
 
 // hasHeader checks if a header is present in the testers canonical chain.