From 4b9d3501a1a5d8c5d50c0a3bead6ad29b4496f3d Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 9 Jan 2021 21:41:28 +0100 Subject: [PATCH] Add timeout of 1 second for each acquire --- Readme.tex | 4 ++-- squinnondation/peers.py | 32 +++++++++++++++++--------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Readme.tex b/Readme.tex index ed8400a..fe4b842 100644 --- a/Readme.tex +++ b/Readme.tex @@ -164,7 +164,7 @@ Le fichier peers.py contient les définitions de la classe des pairs, la classe \section{Choix techniques} -\textbf{Remarque :} Notre projet utilise 5 fils concurrents car il nous a semblé que c'était une manière propre de gérer les actions qui doivent arriver à certains intervalles de temps (envoi de HelloTLV, ...). On a essayé de protéger les accès mémoire via des spinlocks, mais on a rencontré plusieurs problèmes de bloquage en continu des accès, du coup il est possible que certaines fonctions ne soient pas protégées comme elles le devraient. +\textbf{Remarque :} Notre projet utilise 5 fils concurrents car il nous a semblé que c'était une manière propre de gérer les actions qui doivent arriver à certains intervalles de temps (envoi de HelloTLV, ...). On a essayé de protéger les accès mémoire via des spinlocks, mais on a rencontré plusieurs problèmes de bloquage en continu des accès, du coup il est possible que certaines fonctions ne soient pas protégées comme elles le devraient. Afin d'éviter des bloquages infinis, chaque verrou expire au bout d'une seconde. \subsection{Gestion des TLVs} @@ -176,7 +176,7 @@ Les clients sont autorisés à laisser un dernier octet à 0 dans un message de Les messages physiques sont représentés par la classe Packet, qui pourrait permettre l'agrégation de TLVs, bien qu'on ne l'ait pas implémentée. -Le fichier Peer.py contient une classe Message qui est une classe théorique. +Le fichier peer.py contient une classe Message qui est une classe théorique. \subsection{Inondation} diff --git a/squinnondation/peers.py b/squinnondation/peers.py index 51f254d..080bcea 100644 --- a/squinnondation/peers.py +++ b/squinnondation/peers.py @@ -170,7 +170,7 @@ class User(Peer): if (address, port) in self.neighbours: return self.neighbours[(address, port)] - self.data_lock.acquire() + self.data_lock.acquire(timeout=1) peer = Peer(address=address, port=port) self.neighbours[(address, port)] = peer self.data_lock.release() @@ -475,7 +475,7 @@ class User(Peer): if (address, port) in self.neighbours: self.add_system_message("There is already a known client with this address.", ignore_debug=True) return - self.data_lock.acquire() + self.data_lock.acquire(timeout=1) peer = self.new_peer(address, port) self.neighbours[(address, port)] = peer self.data_lock.release() @@ -525,7 +525,7 @@ class User(Peer): return if not args: - self.data_lock.acquire() + self.data_lock.acquire(timeout=1) peers = [self] self.data_lock.release() elif len(args) == 2: @@ -539,7 +539,7 @@ class User(Peer): self.add_system_message("This client is unknown. Please register it by running " f"\"/connect {address} {port}\"", ignore_debug=True) return - self.data_lock.acquire() + self.data_lock.acquire(timeout=1) peers = [self.find_peer(address, port)] self.data_lock.release() else: @@ -617,7 +617,7 @@ class User(Peer): Returns True iff the message was not already received previously. """ - self.data_lock.acquire() + self.data_lock.acquire(timeout=1) if (sender_id, nonce) not in self.received_messages: # If it is a new message, add it to recent_messages d = self.make_inundation_dict() @@ -631,7 +631,7 @@ class User(Peer): if (sender_id, nonce) in self.received_messages: return False - self.data_lock.acquire() + self.data_lock.acquire(timeout=1) self.add_message(msg) # for display purposes self.received_messages[(sender_id, nonce)] = Message(msg, sender_id, nonce) self.data_lock.release() @@ -654,7 +654,7 @@ class User(Peer): """ Remove the sender from the list of neighbours to be inundated """ - self.data_lock.acquire() + self.data_lock.acquire(timeout=1) 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. for addr in peer.addresses: @@ -668,18 +668,18 @@ class User(Peer): """ Remove messages which are overdue (older than 2 minutes) from the inundation dictionnary. """ - self.data_lock.acquire() for key in self.recent_messages.copy(): if time.time() - self.recent_messages[key][1] > 120: + self.data_lock.acquire(timeout=1) self.recent_messages.pop(key) - self.data_lock.release() + self.data_lock.release() def main_inundation(self) -> None: """ The main inundation function. """ - self.data_lock.acquire() - for key in self.recent_messages: + self.data_lock.acquire(timeout=1) + for key in self.recent_messages.copy(): k = list(self.recent_messages[key][2].keys()) for key2 in k: if time.time() >= self.recent_messages[key][2][key2][1]: @@ -811,7 +811,7 @@ class User(Peer): """ Rewrite the history of the messages. """ - self.refresh_lock.acquire() + self.refresh_lock.acquire(timeout=1) y, x = self.squinnondation.screen.getmaxyx() if curses.is_term_resized(curses.LINES, curses.COLS): @@ -846,7 +846,7 @@ class User(Peer): """ Redraw input line. Must not be called while the message is not sent. """ - self.refresh_lock.acquire() + self.refresh_lock.acquire(timeout=1) self.input_pad.erase() color_id = sum(ord(c) for c in self.nickname) % 6 + 1 @@ -873,7 +873,7 @@ class User(Peer): from emoji import unicode_codes - self.refresh_lock.acquire() + self.refresh_lock.acquire(timeout=1) self.emoji_pad.erase() @@ -950,7 +950,7 @@ class User(Peer): We insert the peer into our table of clients. If there is a collision with the address / the ID, then we merge clients into a unique one. """ - self.data_lock.acquire() + self.data_lock.acquire(timeout=1) for addr in peer.addresses: if addr in self.neighbours: @@ -999,6 +999,8 @@ class User(Peer): The program is exited. We send a GoAway to our neighbours, then close the program. """ # Last inundation + self.data_lock.release() + self.refresh_lock.release() self.main_inundation() self.clean_inundation()