From 7c49b583f889887e6e0d21c5514fc3c6839bd1a4 Mon Sep 17 00:00:00 2001 From: BurtonQin Date: Sat, 6 Jun 2020 21:43:56 +0800 Subject: [PATCH] util/network-devp2p: fix possible deadlock caused by conflicting lock order --- util/network-devp2p/src/host.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/util/network-devp2p/src/host.rs b/util/network-devp2p/src/host.rs index 052e8089775..3fe9b593f5d 100644 --- a/util/network-devp2p/src/host.rs +++ b/util/network-devp2p/src/host.rs @@ -759,6 +759,7 @@ impl Host { }, Ok(SessionData::Ready) => { let (_, egress_count, ingress_count) = self.session_count(); + let handlers = self.handlers.read(); let reserved_nodes = self.reserved_nodes.read(); let mut s = session.lock(); let (min_peers, mut max_peers, reserved_only, self_id) = { @@ -822,7 +823,7 @@ impl Host { // Note connection success self.nodes.write().note_success(&id); - for (p, _) in self.handlers.read().iter() { + for (p, _) in handlers.iter() { if s.have_capability(*p) { ready_data.push(*p); } @@ -950,13 +951,14 @@ impl Host { let mut deregister = false; let mut expired_session = None; if let FIRST_SESSION ..= LAST_SESSION = token { + let handlers = self.handlers.read(); let sessions = self.sessions.read(); if let Some(session) = sessions.get(token).cloned() { expired_session = Some(session.clone()); let mut s = session.lock(); if !s.expired() { if s.is_ready() { - for (p, _) in self.handlers.read().iter() { + for (p, _) in handlers.iter() { if s.have_capability(*p) { to_disconnect.push(*p); } @@ -974,8 +976,9 @@ impl Host { } } for p in to_disconnect { + let handlers = self.handlers.read(); let reserved = self.reserved_nodes.read(); - if let Some(h) = self.handlers.read().get(&p) { + if let Some(h) = handlers.get(&p) { h.disconnected(&NetworkContext::new(io, p, expired_session.clone(), self.sessions.clone(), &reserved), &token); } } @@ -1115,11 +1118,13 @@ impl IoHandler for Host { ref versions, } => { let h = handler.clone(); + let mut handlers = self.handlers.write(); let reserved = self.reserved_nodes.read(); h.initialize( &NetworkContext::new(io, *protocol, None, self.sessions.clone(), &reserved), ); - self.handlers.write().insert(*protocol, h); + handlers.insert(*protocol, h); + drop(handlers); let mut info = self.info.write(); for &(version, packet_count) in versions { info.capabilities.push(CapabilityInfo {