diff options
author | Péter Szilágyi <peterke@gmail.com> | 2016-08-09 16:39:24 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-09 16:39:24 +0800 |
commit | b46b36729f1623ee91a2467f31285e33067fa4b8 (patch) | |
tree | 7eba1858936f0f0e2073e0673bf5876e8c20980f /eth | |
parent | 893fabd3360b3aeba75477f22c85463b6e3ea2bc (diff) | |
parent | 8f0a4a25f82f48005e6252a90c008bdc76219cc3 (diff) | |
download | go-tangerine-b46b36729f1623ee91a2467f31285e33067fa4b8.tar.gz go-tangerine-b46b36729f1623ee91a2467f31285e33067fa4b8.tar.zst go-tangerine-b46b36729f1623ee91a2467f31285e33067fa4b8.zip |
Merge pull request #2868 from karalabe/downloader-abort-master-drop
eth/downloader: abort sync if master drops (timeout prev)
Diffstat (limited to 'eth')
-rw-r--r-- | eth/downloader/downloader.go | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 2aea30b39..b6b9d54f0 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -147,8 +147,10 @@ type Downloader struct { stateWakeCh chan bool // [eth/63] Channel to signal the state fetcher of new tasks headerProcCh chan []*types.Header // [eth/62] Channel to feed the header processor new tasks + // 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 in delivers + cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers quitCh chan struct{} // Quit channel to signal termination quitLock sync.RWMutex // Lock to prevent double closes @@ -254,12 +256,22 @@ func (d *Downloader) RegisterPeer(id string, version int, currentHead currentHea // the specified peer. An effort is also made to return any pending fetches into // the queue. func (d *Downloader) UnregisterPeer(id string) error { + // Unregister the peer from the active peer set and revoke any fetch tasks glog.V(logger.Detail).Infoln("Unregistering peer", id) if err := d.peers.Unregister(id); err != nil { glog.V(logger.Error).Infoln("Unregister failed:", err) return err } d.queue.Revoke(id) + + // If this peer was the master peer, abort sync immediately + d.cancelLock.RLock() + master := id == d.cancelPeer + d.cancelLock.RUnlock() + + if master { + d.cancel() + } return nil } @@ -332,9 +344,10 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode empty = true } } - // Create cancel channel for aborting mid-flight + // Create cancel channel for aborting mid-flight and mark the master peer d.cancelLock.Lock() d.cancelCh = make(chan struct{}) + d.cancelPeer = id d.cancelLock.Unlock() defer d.cancel() // No matter what, we can't leave the cancel channel open |