Add timeout of 1 second for each acquire

This commit is contained in:
Yohann D'ANELLO 2021-01-09 21:41:28 +01:00
parent 6aa714ef4c
commit 4b9d3501a1
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
2 changed files with 19 additions and 17 deletions

View File

@ -164,7 +164,7 @@ Le fichier peers.py contient les définitions de la classe des pairs, la classe
\section{Choix techniques} \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} \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. 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} \subsection{Inondation}

View File

@ -170,7 +170,7 @@ class User(Peer):
if (address, port) in self.neighbours: if (address, port) in self.neighbours:
return self.neighbours[(address, port)] return self.neighbours[(address, port)]
self.data_lock.acquire() self.data_lock.acquire(timeout=1)
peer = Peer(address=address, port=port) peer = Peer(address=address, port=port)
self.neighbours[(address, port)] = peer self.neighbours[(address, port)] = peer
self.data_lock.release() self.data_lock.release()
@ -475,7 +475,7 @@ 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() self.data_lock.acquire(timeout=1)
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.data_lock.release()
@ -525,7 +525,7 @@ class User(Peer):
return return
if not args: if not args:
self.data_lock.acquire() self.data_lock.acquire(timeout=1)
peers = [self] peers = [self]
self.data_lock.release() self.data_lock.release()
elif len(args) == 2: elif len(args) == 2:
@ -539,7 +539,7 @@ 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() self.data_lock.acquire(timeout=1)
peers = [self.find_peer(address, port)] peers = [self.find_peer(address, port)]
self.data_lock.release() self.data_lock.release()
else: else:
@ -617,7 +617,7 @@ class User(Peer):
Returns True iff the message was not already received previously. 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 (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
d = self.make_inundation_dict() d = self.make_inundation_dict()
@ -631,7 +631,7 @@ class User(Peer):
if (sender_id, nonce) in self.received_messages: if (sender_id, nonce) in self.received_messages:
return False return False
self.data_lock.acquire() self.data_lock.acquire(timeout=1)
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() self.data_lock.release()
@ -654,7 +654,7 @@ class User(Peer):
""" """
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() self.data_lock.acquire(timeout=1)
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,9 +668,9 @@ class User(Peer):
""" """
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.copy(): for key in self.recent_messages.copy():
if time.time() - self.recent_messages[key][1] > 120: if time.time() - self.recent_messages[key][1] > 120:
self.data_lock.acquire(timeout=1)
self.recent_messages.pop(key) self.recent_messages.pop(key)
self.data_lock.release() self.data_lock.release()
@ -678,8 +678,8 @@ class User(Peer):
""" """
The main inundation function. The main inundation function.
""" """
self.data_lock.acquire() self.data_lock.acquire(timeout=1)
for key in self.recent_messages: for key in self.recent_messages.copy():
k = list(self.recent_messages[key][2].keys()) k = list(self.recent_messages[key][2].keys())
for key2 in k: for key2 in k:
if time.time() >= self.recent_messages[key][2][key2][1]: if time.time() >= self.recent_messages[key][2][key2][1]:
@ -811,7 +811,7 @@ class User(Peer):
""" """
Rewrite the history of the messages. Rewrite the history of the messages.
""" """
self.refresh_lock.acquire() self.refresh_lock.acquire(timeout=1)
y, x = self.squinnondation.screen.getmaxyx() y, x = self.squinnondation.screen.getmaxyx()
if curses.is_term_resized(curses.LINES, curses.COLS): 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. 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() self.input_pad.erase()
color_id = sum(ord(c) for c in self.nickname) % 6 + 1 color_id = sum(ord(c) for c in self.nickname) % 6 + 1
@ -873,7 +873,7 @@ class User(Peer):
from emoji import unicode_codes from emoji import unicode_codes
self.refresh_lock.acquire() self.refresh_lock.acquire(timeout=1)
self.emoji_pad.erase() self.emoji_pad.erase()
@ -950,7 +950,7 @@ class User(Peer):
We insert the peer into our table of clients. 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. 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: for addr in peer.addresses:
if addr in self.neighbours: 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. The program is exited. We send a GoAway to our neighbours, then close the program.
""" """
# Last inundation # Last inundation
self.data_lock.release()
self.refresh_lock.release()
self.main_inundation() self.main_inundation()
self.clean_inundation() self.clean_inundation()