From 8d97227965ef920953737a3c4056a2dc35e9e847 Mon Sep 17 00:00:00 2001 From: Giuseppe Guerra Date: Sat, 12 Aug 2017 19:07:28 +0200 Subject: [PATCH] Fix race condition while iterating over clients --- constants/fokabotCommands.py | 14 ++++++++------ events/loginEvent.py | 7 ++++--- objects/tokenList.py | 7 +++++++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/constants/fokabotCommands.py b/constants/fokabotCommands.py index 913d7a5..073dac5 100644 --- a/constants/fokabotCommands.py +++ b/constants/fokabotCommands.py @@ -114,9 +114,10 @@ def moderated(fro, chan, message): def kickAll(fro, chan, message): # Kick everyone but mods/admins toKick = [] - for key, value in glob.tokens.tokens.items(): - if not value.admin: - toKick.append(key) + with glob.tokens: + for key, value in glob.tokens.tokens.items(): + if not value.admin: + toKick.append(key) # Loop though users to kick (we can't change dictionary size while iterating) for i in toKick: @@ -336,9 +337,10 @@ def systemMaintenance(fro, chan, message): who = [] # Disconnect everyone but mod/admins - for _, value in glob.tokens.tokens.items(): - if not value.admin: - who.append(value.userID) + with glob.tokens: + for _, value in glob.tokens.tokens.items(): + if not value.admin: + who.append(value.userID) glob.streams.broadcast("main", serverPackets.notification("Our bancho server is in maintenance mode. Please try to login again later.")) glob.tokens.multipleEnqueue(serverPackets.loginError(), who) diff --git a/events/loginEvent.py b/events/loginEvent.py index 9ff591a..bc65b55 100644 --- a/events/loginEvent.py +++ b/events/loginEvent.py @@ -184,9 +184,10 @@ def handle(tornadoRequest): responseToken.enqueue(serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"])) # Send online users' panels - for _, token in glob.tokens.tokens.items(): - if not token.restricted: - responseToken.enqueue(serverPackets.userPanel(token.userID)) + with glob.tokens: + for _, token in glob.tokens.tokens.items(): + if not token.restricted: + responseToken.enqueue(serverPackets.userPanel(token.userID)) # Get location and country from ip.zxq.co or database if glob.localize: diff --git a/objects/tokenList.py b/objects/tokenList.py index bfeb5cb..c37fe25 100644 --- a/objects/tokenList.py +++ b/objects/tokenList.py @@ -13,6 +13,13 @@ from objects import osuToken class tokenList: def __init__(self): self.tokens = {} + self._lock = threading.Lock() + + def __enter__(self): + self._lock.acquire() + + def __exit__(self, exc_type, exc_val, exc_tb): + self._lock.release() def addToken(self, userID, ip = "", irc = False, timeOffset=0, tournament=False): """