@@ -147,8 +147,10 @@ type Downloader struct {
147
147
stateWakeCh chan bool // [eth/63] Channel to signal the state fetcher of new tasks
148
148
headerProcCh chan []* types.Header // [eth/62] Channel to feed the header processor new tasks
149
149
150
+ // Cancellation and termination
151
+ cancelPeer string // Identifier of the peer currently being used as the master (cancel on drop)
150
152
cancelCh chan struct {} // Channel to cancel mid-flight syncs
151
- cancelLock sync.RWMutex // Lock to protect the cancel channel in delivers
153
+ cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers
152
154
153
155
quitCh chan struct {} // Quit channel to signal termination
154
156
quitLock sync.RWMutex // Lock to prevent double closes
@@ -254,12 +256,22 @@ func (d *Downloader) RegisterPeer(id string, version int, currentHead currentHea
254
256
// the specified peer. An effort is also made to return any pending fetches into
255
257
// the queue.
256
258
func (d * Downloader ) UnregisterPeer (id string ) error {
259
+ // Unregister the peer from the active peer set and revoke any fetch tasks
257
260
glog .V (logger .Detail ).Infoln ("Unregistering peer" , id )
258
261
if err := d .peers .Unregister (id ); err != nil {
259
262
glog .V (logger .Error ).Infoln ("Unregister failed:" , err )
260
263
return err
261
264
}
262
265
d .queue .Revoke (id )
266
+
267
+ // If this peer was the master peer, abort sync immediately
268
+ d .cancelLock .RLock ()
269
+ master := id == d .cancelPeer
270
+ d .cancelLock .RUnlock ()
271
+
272
+ if master {
273
+ d .cancel ()
274
+ }
263
275
return nil
264
276
}
265
277
@@ -332,9 +344,10 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode
332
344
empty = true
333
345
}
334
346
}
335
- // Create cancel channel for aborting mid-flight
347
+ // Create cancel channel for aborting mid-flight and mark the master peer
336
348
d .cancelLock .Lock ()
337
349
d .cancelCh = make (chan struct {})
350
+ d .cancelPeer = id
338
351
d .cancelLock .Unlock ()
339
352
340
353
defer d .cancel () // No matter what, we can't leave the cancel channel open
0 commit comments