Archived
1
0
Fork 0

Add RLock on clients dictionary for safe shared resources

This commit is contained in:
Ethanell 2019-07-21 20:18:39 +02:00
parent da0e1549a2
commit 6e47a44184

View file

@ -1,4 +1,4 @@
from threading import Thread from threading import Thread, RLock
from SecureSocketService import Socket from SecureSocketService import Socket
from socket import error as socket_error from socket import error as socket_error
@ -14,6 +14,7 @@ class Server(Socket):
self.welcome_msg = "Welcome ! Type \"/help\" to see commands and \"quit\" to exit" self.welcome_msg = "Welcome ! Type \"/help\" to see commands and \"quit\" to exit"
self.commands = {"help": self.command_help, "players list": self.command_players_list} self.commands = {"help": self.command_help, "players list": self.command_players_list}
self.clients = dict() self.clients = dict()
self.clients_lock = RLock()
print("Wait for connexion...") print("Wait for connexion...")
Thread(target=self.connexion).start() Thread(target=self.connexion).start()
@ -26,8 +27,9 @@ class Server(Socket):
else: else:
name = self.client_name(c) name = self.client_name(c)
if name: if name:
self.clients[name] = c with self.clients_lock:
self.send(self.clients[name], self.welcome_msg) self.clients[name] = c
self.send(c, self.welcome_msg)
self.broadcast(f"{name} is online !") self.broadcast(f"{name} is online !")
Thread(target=self.listen_client, args=(name,)).start() Thread(target=self.listen_client, args=(name,)).start()
@ -36,13 +38,14 @@ class Server(Socket):
try: try:
self.send(sock, "Your name ?") self.send(sock, "Your name ?")
name = self.receive(sock) name = self.receive(sock)
if name in self.clients: with self.clients_lock:
self.send(sock, "Name already taken !") if name in self.clients:
elif name.lower() == "quit": self.send(sock, "Name already taken !")
sock.close() elif name.lower() == "quit":
name = None sock.close()
else: name = None
break else:
break
except socket_error: except socket_error:
name = None name = None
break break
@ -62,21 +65,23 @@ class Server(Socket):
def broadcast(self, message): def broadcast(self, message):
print(message) print(message)
for i in self.clients: with self.clients_lock:
try: for i in self.clients:
self.send(self.clients[i], message) try:
except socket_error: self.send(self.clients[i], message)
continue except socket_error:
continue
def client_quit(self, name): def client_quit(self, name):
try: with self.clients_lock:
self.send(self.clients[name], "quit") try:
self.clients[name].close() self.send(self.clients[name], "quit")
except socket_error: self.clients[name].close()
pass except socket_error:
finally: pass
del self.clients[name] finally:
self.broadcast(f"{name} is offline !") del self.clients[name]
self.broadcast(f"{name} is offline !")
def command(self, command, author): def command(self, command, author):
command = command.lower() command = command.lower()
@ -99,13 +104,15 @@ class Server(Socket):
message = "[Help]" message = "[Help]"
for i in self.commands: for i in self.commands:
message += "\n- " + i message += "\n- " + i
self.send(self.clients[author], message) with self.clients_lock:
self.send(self.clients[author], message)
def command_players_list(self, author): def command_players_list(self, author):
message = f"[Players list | {len(self.clients)} online]" with self.clients_lock:
for i in self.clients: message = f"[Players list | {len(self.clients)} online]"
message += "\n- " + i for i in self.clients:
self.send(self.clients[author], message) message += "\n- " + i
self.send(self.clients[author], message)
if __name__ == "__main__": if __name__ == "__main__":