mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
p2p/simulations: avoid holding Network lock while stopping node
This fixes a rare deadlock with the inproc adapter: - A node is stopped, which acquires Network.lock. - The protocol code being simulated (swarm/network in my case) waits for its goroutines to shut down. - One of those goroutines calls into the simulation to add a peer, which waits for Network.lock.
This commit is contained in:
parent
dd6751488c
commit
bfa7e3fe75
1 changed files with 9 additions and 5 deletions
|
|
@ -250,7 +250,6 @@ func (net *Network) watchPeerEvents(id enode.ID, events chan *p2p.PeerEvent, sub
|
||||||
// Stop stops the node with the given ID
|
// Stop stops the node with the given ID
|
||||||
func (net *Network) Stop(id enode.ID) error {
|
func (net *Network) Stop(id enode.ID) error {
|
||||||
net.lock.Lock()
|
net.lock.Lock()
|
||||||
defer net.lock.Unlock()
|
|
||||||
node := net.getNode(id)
|
node := net.getNode(id)
|
||||||
if node == nil {
|
if node == nil {
|
||||||
return fmt.Errorf("node %v does not exist", id)
|
return fmt.Errorf("node %v does not exist", id)
|
||||||
|
|
@ -258,12 +257,17 @@ func (net *Network) Stop(id enode.ID) error {
|
||||||
if !node.Up {
|
if !node.Up {
|
||||||
return fmt.Errorf("node %v already down", id)
|
return fmt.Errorf("node %v already down", id)
|
||||||
}
|
}
|
||||||
if err := node.Stop(); err != nil {
|
node.Up = false
|
||||||
|
net.lock.Unlock()
|
||||||
|
|
||||||
|
err := node.Stop()
|
||||||
|
if err != nil {
|
||||||
|
net.lock.Lock()
|
||||||
|
node.Up = true
|
||||||
|
net.lock.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
node.Up = false
|
log.Info("Stopped node", "id", id, "err", err)
|
||||||
log.Info(fmt.Sprintf("stop node %v: %v", id, node.Up))
|
|
||||||
|
|
||||||
net.events.Send(ControlEvent(node))
|
net.events.Send(ControlEvent(node))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue