Removes somr locks that were blocking the threads
This commit is contained in:
		@@ -117,7 +117,7 @@ class User(Peer):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # Lock the refresh function in order to avoid concurrent refresh
 | 
					        # Lock the refresh function in order to avoid concurrent refresh
 | 
				
			||||||
        self.refresh_lock = RLock()
 | 
					        self.refresh_lock = RLock()
 | 
				
			||||||
        # Lock functions that can be used by two threads to avoid concurrent refresh
 | 
					        # Lock functions that can be used by two threads to avoid concurrent writing
 | 
				
			||||||
        self.data_lock = RLock()
 | 
					        self.data_lock = RLock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.history = []
 | 
					        self.history = []
 | 
				
			||||||
@@ -182,25 +182,18 @@ class User(Peer):
 | 
				
			|||||||
        Retrieve the peer that is known by its id. Return None if it is unknown.
 | 
					        Retrieve the peer that is known by its id. Return None if it is unknown.
 | 
				
			||||||
        The given identifier must be positive.
 | 
					        The given identifier must be positive.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if peer_id > 0:
 | 
					        if peer_id > 0:
 | 
				
			||||||
            for peer in self.neighbours.values():
 | 
					            for peer in self.neighbours.values():
 | 
				
			||||||
                if peer.id == peer_id:
 | 
					                if peer.id == peer_id:
 | 
				
			||||||
                    return peer
 | 
					                    return peer
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def find_peer_by_nickname(self, nickname: str) -> Generator[Peer, Any, None]:
 | 
					    def find_peer_by_nickname(self, nickname: str) -> Generator[Peer, Any, None]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Retrieve the peers that are known by their nicknames.
 | 
					        Retrieve the peers that are known by their nicknames.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        for peer in self.neighbours.values():
 | 
					        for peer in self.neighbours.values():
 | 
				
			||||||
            if peer.nickname == nickname:
 | 
					            if peer.nickname == nickname:
 | 
				
			||||||
                yield peer
 | 
					                yield peer
 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def send_packet(self, client: Peer, pkt: Packet) -> int:
 | 
					    def send_packet(self, client: Peer, pkt: Packet) -> int:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@@ -426,7 +419,6 @@ class User(Peer):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        The user sent a command. We analyse it and process what is needed.
 | 
					        The user sent a command. We analyse it and process what is needed.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        def resolve_address(address: str) -> str:
 | 
					        def resolve_address(address: str) -> str:
 | 
				
			||||||
            # Resolve address
 | 
					            # Resolve address
 | 
				
			||||||
@@ -483,8 +475,10 @@ class User(Peer):
 | 
				
			|||||||
            if (address, port) in self.neighbours:
 | 
					            if (address, port) in self.neighbours:
 | 
				
			||||||
                self.add_system_message("There is already a known client with this address.", ignore_debug=True)
 | 
					                self.add_system_message("There is already a known client with this address.", ignore_debug=True)
 | 
				
			||||||
                return
 | 
					                return
 | 
				
			||||||
 | 
					            self.data_lock.acquire()
 | 
				
			||||||
            peer = self.new_peer(address, port)
 | 
					            peer = self.new_peer(address, port)
 | 
				
			||||||
            self.neighbours[(address, port)] = peer
 | 
					            self.neighbours[(address, port)] = peer
 | 
				
			||||||
 | 
					            self.data_lock.release()
 | 
				
			||||||
            self.add_system_message(f"Potential client successfully added! You can send a hello by running "
 | 
					            self.add_system_message(f"Potential client successfully added! You can send a hello by running "
 | 
				
			||||||
                                    f"\"/hello {address} {port}\".", ignore_debug=True)
 | 
					                                    f"\"/hello {address} {port}\".", ignore_debug=True)
 | 
				
			||||||
        elif command == "hello":
 | 
					        elif command == "hello":
 | 
				
			||||||
@@ -531,7 +525,9 @@ class User(Peer):
 | 
				
			|||||||
                return
 | 
					                return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if not args:
 | 
					            if not args:
 | 
				
			||||||
 | 
					                self.data_lock.acquire()
 | 
				
			||||||
                peers = [self]
 | 
					                peers = [self]
 | 
				
			||||||
 | 
					                self.data_lock.release()
 | 
				
			||||||
            elif len(args) == 2:
 | 
					            elif len(args) == 2:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    address, port = resolve_address(args[0]), resolve_port(args[1])
 | 
					                    address, port = resolve_address(args[0]), resolve_port(args[1])
 | 
				
			||||||
@@ -543,8 +539,9 @@ class User(Peer):
 | 
				
			|||||||
                    self.add_system_message("This client is unknown. Please register it by running "
 | 
					                    self.add_system_message("This client is unknown. Please register it by running "
 | 
				
			||||||
                                            f"\"/connect {address} {port}\"", ignore_debug=True)
 | 
					                                            f"\"/connect {address} {port}\"", ignore_debug=True)
 | 
				
			||||||
                    return
 | 
					                    return
 | 
				
			||||||
 | 
					                self.data_lock.acquire()
 | 
				
			||||||
                peers = [self.find_peer(address, port)]
 | 
					                peers = [self.find_peer(address, port)]
 | 
				
			||||||
 | 
					                self.data_lock.release()
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                peers = list(self.find_peer_by_nickname(args[0]))
 | 
					                peers = list(self.find_peer_by_nickname(args[0]))
 | 
				
			||||||
                if args[0].isnumeric():
 | 
					                if args[0].isnumeric():
 | 
				
			||||||
@@ -604,8 +601,6 @@ class User(Peer):
 | 
				
			|||||||
                ignore_debug=True)
 | 
					                ignore_debug=True)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.add_system_message("Unknown command. Please do /help to see available commands.", ignore_debug=True)
 | 
					            self.add_system_message("Unknown command. Please do /help to see available commands.", ignore_debug=True)
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def add_message(self, msg: str) -> None:
 | 
					    def add_message(self, msg: str) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@@ -621,7 +616,6 @@ class User(Peer):
 | 
				
			|||||||
        This add the message in the history if not already done.
 | 
					        This add the message in the history if not already done.
 | 
				
			||||||
        Returns True iff the message was not already received previously.
 | 
					        Returns True iff the message was not already received previously.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (sender_id, nonce) not in self.received_messages:
 | 
					        if (sender_id, nonce) not in self.received_messages:
 | 
				
			||||||
            # If it is a new message, add it to recent_messages
 | 
					            # If it is a new message, add it to recent_messages
 | 
				
			||||||
@@ -638,29 +632,24 @@ class User(Peer):
 | 
				
			|||||||
        self.add_message(msg)  # for display purposes
 | 
					        self.add_message(msg)  # for display purposes
 | 
				
			||||||
        self.received_messages[(sender_id, nonce)] = Message(msg, sender_id, nonce)
 | 
					        self.received_messages[(sender_id, nonce)] = Message(msg, sender_id, nonce)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def make_inundation_dict(self) -> dict:
 | 
					    def make_inundation_dict(self) -> dict:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Takes the active peers dictionnary and returns a list of [peer, date+random, 0]
 | 
					        Takes the active peers dictionnary and returns a list of [peer, date+random, 0]
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        res = dict()
 | 
					        res = dict()
 | 
				
			||||||
        peers = self.active_peers
 | 
					        peers = self.active_peers
 | 
				
			||||||
        for peer in peers:
 | 
					        for peer in peers:
 | 
				
			||||||
            if peer.symmetric:
 | 
					            if peer.symmetric:
 | 
				
			||||||
                next_send = uniform(1, 2)
 | 
					                next_send = uniform(1, 2)
 | 
				
			||||||
                res[peer.main_address] = [peer, time.time() + next_send, 0]
 | 
					                res[peer.main_address] = [peer, time.time() + next_send, 0]
 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
        return res
 | 
					        return res
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def remove_from_inundation(self, peer: Peer, sender_id: int, nonce: int) -> None:
 | 
					    def remove_from_inundation(self, peer: Peer, sender_id: int, nonce: int) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Remove the sender from the list of neighbours to be inundated
 | 
					        Remove the sender from the list of neighbours to be inundated
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        if (sender_id, nonce) in self.recent_messages:
 | 
					        if (sender_id, nonce) in self.recent_messages:
 | 
				
			||||||
            # If a peer is late in its acknowledgement, the absence of the previous if causes an error.
 | 
					            # If a peer is late in its acknowledgement, the absence of the previous if causes an error.
 | 
				
			||||||
            for addr in peer.addresses:
 | 
					            for addr in peer.addresses:
 | 
				
			||||||
@@ -668,17 +657,14 @@ class User(Peer):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if not self.recent_messages[(sender_id, nonce)][2]:  # If dictionnary is empty, remove the message
 | 
					            if not self.recent_messages[(sender_id, nonce)][2]:  # If dictionnary is empty, remove the message
 | 
				
			||||||
                self.recent_messages.pop((sender_id, nonce), None)
 | 
					                self.recent_messages.pop((sender_id, nonce), None)
 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def clean_inundation(self) -> None:
 | 
					    def clean_inundation(self) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Remove messages which are overdue (older than 2 minutes) from the inundation dictionnary.
 | 
					        Remove messages which are overdue (older than 2 minutes) from the inundation dictionnary.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        for key in self.recent_messages:
 | 
					        for key in self.recent_messages:
 | 
				
			||||||
            if time.time() - self.recent_messages[key][1] > 120:
 | 
					            if time.time() - self.recent_messages[key][1] > 120:
 | 
				
			||||||
                self.recent_messages.pop(key)
 | 
					                self.recent_messages.pop(key)
 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def main_inundation(self) -> None:
 | 
					    def main_inundation(self) -> None:
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@@ -693,7 +679,7 @@ class User(Peer):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    # send the packet if it is overdue
 | 
					                    # send the packet if it is overdue
 | 
				
			||||||
                    self.send_packet(self.recent_messages[key][2][key2][0], self.recent_messages[key][0])
 | 
					                    self.send_packet(self.recent_messages[key][2][key2][0], self.recent_messages[key][0])
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
                    # change the time until the next send
 | 
					                    # change the time until the next send
 | 
				
			||||||
                    a = self.recent_messages[key][2][key2][2]
 | 
					                    a = self.recent_messages[key][2][key2][2]
 | 
				
			||||||
                    self.recent_messages[key][2][key2][2] = a + 1
 | 
					                    self.recent_messages[key][2][key2][2] = a + 1
 | 
				
			||||||
@@ -907,8 +893,6 @@ class User(Peer):
 | 
				
			|||||||
        Returns a list of peers the user should contact if it does
 | 
					        Returns a list of peers the user should contact if it does
 | 
				
			||||||
        not have enough symmetric neighbours.
 | 
					        not have enough symmetric neighbours.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        res = []
 | 
					        res = []
 | 
				
			||||||
        val = list(self.potential_peers)
 | 
					        val = list(self.potential_peers)
 | 
				
			||||||
        lp = len(val)
 | 
					        lp = len(val)
 | 
				
			||||||
@@ -916,30 +900,22 @@ class User(Peer):
 | 
				
			|||||||
        for i in range(min(lp, max(0, self.minNS - self.nbNS))):
 | 
					        for i in range(min(lp, max(0, self.minNS - self.nbNS))):
 | 
				
			||||||
            a = randint(0, lp - 1)
 | 
					            a = randint(0, lp - 1)
 | 
				
			||||||
            res.append(val[a])
 | 
					            res.append(val[a])
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
        return res
 | 
					        return res
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def send_hello(self) -> None:
 | 
					    def send_hello(self) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Sends a long HelloTLV to all active neighbours.
 | 
					        Sends a long HelloTLV to all active neighbours.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        for peer in self.active_peers:
 | 
					        for peer in self.active_peers:
 | 
				
			||||||
            htlv = HelloTLV().construct(16, self, peer)
 | 
					            htlv = HelloTLV().construct(16, self, peer)
 | 
				
			||||||
            pkt = Packet().construct(htlv)
 | 
					            pkt = Packet().construct(htlv)
 | 
				
			||||||
            self.send_packet(peer, pkt)
 | 
					            self.send_packet(peer, pkt)
 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def verify_activity(self) -> None:
 | 
					    def verify_activity(self) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        All neighbours that have not sent a HelloTLV in the last 2
 | 
					        All neighbours that have not sent a HelloTLV in the last 2
 | 
				
			||||||
        minutes are considered not active.
 | 
					        minutes are considered not active.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        val = list(self.active_peers)  # create a copy because the dict size will change
 | 
					        val = list(self.active_peers)  # create a copy because the dict size will change
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for peer in val:
 | 
					        for peer in val:
 | 
				
			||||||
@@ -949,8 +925,6 @@ class User(Peer):
 | 
				
			|||||||
                self.send_packet(peer, pkt)
 | 
					                self.send_packet(peer, pkt)
 | 
				
			||||||
                peer.active = False
 | 
					                peer.active = False
 | 
				
			||||||
                self.update_peer_table(peer)
 | 
					                self.update_peer_table(peer)
 | 
				
			||||||
                
 | 
					 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update_peer_table(self, peer: Peer) -> None:
 | 
					    def update_peer_table(self, peer: Peer) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@@ -978,7 +952,6 @@ class User(Peer):
 | 
				
			|||||||
        Update the number of symmetric neighbours and
 | 
					        Update the number of symmetric neighbours and
 | 
				
			||||||
        send all neighbours NeighbourTLV
 | 
					        send all neighbours NeighbourTLV
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.data_lock.acquire()
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        nb_ns = 0
 | 
					        nb_ns = 0
 | 
				
			||||||
        # could send the same to all neighbour, but it means that neighbour
 | 
					        # could send the same to all neighbour, but it means that neighbour
 | 
				
			||||||
@@ -995,8 +968,6 @@ class User(Peer):
 | 
				
			|||||||
            else:
 | 
					            else:
 | 
				
			||||||
                peer.symmetric = False
 | 
					                peer.symmetric = False
 | 
				
			||||||
        self.nbNS = nb_ns
 | 
					        self.nbNS = nb_ns
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        self.data_lock.release()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def leave(self) -> None:
 | 
					    def leave(self) -> None:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user