Dont hold peers lock when calling user code
authorMatt Corallo <git@bluematt.me>
Sun, 1 Mar 2020 03:03:53 +0000 (22:03 -0500)
committerMatt Corallo <git@bluematt.me>
Mon, 25 May 2020 19:33:02 +0000 (15:33 -0400)
lightning/src/ln/peer_handler.rs

index c02e351bef3bc1169d6cdfffb054e6ef611d51f9..692e6769a4bf8fe579441374aef4fecaf251dc9a 100644 (file)
@@ -1136,18 +1136,30 @@ impl<Descriptor: SocketDescriptor, CM: Deref, L: Deref> PeerManager<Descriptor,
 
        /// Will most likely call send_data on all of the registered descriptors, thus, be very careful with reentrancy issues!
        pub fn timer_tick_occured(&self) {
-               let mut peers_lock = self.peers.lock().unwrap();
+               let mut descriptors_needing_disconnect = Vec::new();
                {
+                       let peers_lock = self.peers.lock().unwrap();
+                       for (descriptor, peer) in peers_lock.peers.iter() {
+                               if peer.awaiting_pong {
+                                       descriptors_needing_disconnect.push(descriptor.clone());
+                               }
+                       }
+               }
+
+               for mut descriptor in descriptors_needing_disconnect.drain(..) {
+                       descriptor.disconnect_socket();
+               }
+
+               {
+                       let mut peers_lock = self.peers.lock().unwrap();
                        let peers = &mut *peers_lock;
                        let peers_needing_send = &mut peers.peers_needing_send;
                        let node_id_to_descriptor = &mut peers.node_id_to_descriptor;
                        let peers = &mut peers.peers;
-                       let mut descriptors_needing_disconnect = Vec::new();
 
                        peers.retain(|descriptor, peer| {
                                if peer.awaiting_pong {
                                        peers_needing_send.remove(descriptor);
-                                       descriptors_needing_disconnect.push(descriptor.clone());
                                        match peer.their_node_id {
                                                Some(node_id) => {
                                                        log_trace!(self.logger, "Disconnecting peer with id {} due to ping timeout", node_id);
@@ -1180,10 +1192,6 @@ impl<Descriptor: SocketDescriptor, CM: Deref, L: Deref> PeerManager<Descriptor,
                                peer.awaiting_pong = true;
                                true
                        });
-
-                       for mut descriptor in descriptors_needing_disconnect.drain(..) {
-                               descriptor.disconnect_socket();
-                       }
                }
        }
 }