Make gamedblock intrinsic to GameDB itself (i.e. let it contain its own lock)
* Return generators instead of entire lists and have the generator keep the lock intact while it's being iterated over git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@7266 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
3153a9f63d
commit
0c7f44ee70
|
@ -42,7 +42,7 @@ from SocketServer import ThreadingTCPServer
|
||||||
import SocketServer
|
import SocketServer
|
||||||
import struct
|
import struct
|
||||||
import socket
|
import socket
|
||||||
from threading import Lock, Thread, Event, Timer
|
from threading import Lock, RLock, Thread, Event, Timer
|
||||||
from select import select
|
from select import select
|
||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
|
@ -64,13 +64,11 @@ logging.basicConfig(level = logging.DEBUG, format = "%(asctime)-15s %(levelname)
|
||||||
# Game DB
|
# Game DB
|
||||||
|
|
||||||
gamedb = None
|
gamedb = None
|
||||||
gamedblock = Lock()
|
|
||||||
|
|
||||||
class GameDB:
|
class GameDB:
|
||||||
global gamedblock
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.list = set()
|
self.list = set()
|
||||||
|
self.lock = RLock()
|
||||||
|
|
||||||
def __remove(self, g):
|
def __remove(self, g):
|
||||||
# if g is not in the list, ignore the KeyError exception
|
# if g is not in the list, ignore the KeyError exception
|
||||||
|
@ -81,41 +79,47 @@ class GameDB:
|
||||||
|
|
||||||
def addGame(self, g):
|
def addGame(self, g):
|
||||||
""" add a game """
|
""" add a game """
|
||||||
with gamedblock:
|
with self.lock:
|
||||||
self.list.add(g)
|
self.list.add(g)
|
||||||
|
|
||||||
def removeGame(self, g):
|
def removeGame(self, g):
|
||||||
""" remove a game from the list"""
|
""" remove a game from the list"""
|
||||||
with gamedblock:
|
with self.lock:
|
||||||
self.__remove(g)
|
self.__remove(g)
|
||||||
|
|
||||||
# only games with a valid description
|
# only games with a valid description
|
||||||
def getGames(self):
|
def getGames(self):
|
||||||
""" filter all games with a valid description """
|
""" filter all games with a valid description """
|
||||||
return filter(lambda x: x.description, self.list)
|
for game in self.getAllGames()
|
||||||
|
if game.description:
|
||||||
|
yield game
|
||||||
|
|
||||||
def getAllGames(self):
|
def getAllGames(self):
|
||||||
""" return all knwon games """
|
""" return all knwon games """
|
||||||
return self.list
|
with self.lock:
|
||||||
|
for game in self.list:
|
||||||
|
yield game
|
||||||
|
|
||||||
def getGamesByHost(self, host):
|
def getGamesByHost(self, host):
|
||||||
""" filter all games of a certain host"""
|
""" filter all games of a certain host"""
|
||||||
return filter(lambda x: x.host == host, self.getGames())
|
for game in self.getGames():
|
||||||
|
if game.host == host:
|
||||||
|
yield game
|
||||||
|
|
||||||
def checkGames(self):
|
def checkGames(self):
|
||||||
with gamedblock:
|
with self.lock:
|
||||||
gamesCount = len(self.getGames())
|
games = list(self.getGames())
|
||||||
logging.debug("Checking: %i game(s)" % (gamesCount))
|
logging.debug("Checking: %i game(s)" % (len(games)))
|
||||||
for game in self.getGames():
|
for game in games:
|
||||||
if not protocol.check(game):
|
if not protocol.check(game):
|
||||||
logging.debug("Removing unreachable game: %s" % game)
|
logging.debug("Removing unreachable game: %s" % game)
|
||||||
self.__remove(game)
|
self.__remove(game)
|
||||||
|
|
||||||
def listGames(self):
|
def listGames(self):
|
||||||
with gamedblock:
|
with self.lock:
|
||||||
gamesCount = len(self.getGames())
|
games = list(self.getGames())
|
||||||
logging.debug("Gameserver list: %i game(s)" % (gamesCount))
|
logging.debug("Gameserver list: %i game(s)" % (len(games)))
|
||||||
for game in self.getGames():
|
for game in games:
|
||||||
logging.debug(" %s" % game)
|
logging.debug(" %s" % game)
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -200,15 +204,15 @@ class RequestHandler(SocketServer.ThreadingMixIn, SocketServer.StreamRequestHand
|
||||||
# Get a game list.
|
# Get a game list.
|
||||||
elif netCommand == 'list':
|
elif netCommand == 'list':
|
||||||
# Lock the gamelist to prevent new games while output.
|
# Lock the gamelist to prevent new games while output.
|
||||||
with gamedblock:
|
with gamedb.lock:
|
||||||
try:
|
try:
|
||||||
gamesCount = len(gamedb.getGames())
|
games = list(gamedb.getGames())
|
||||||
logging.debug("(%s) Gameserver list: %i game(s)" % (gameHost, gamesCount))
|
logging.debug("(%s) Gameserver list: %i game(s)" % (gameHost, len(games)))
|
||||||
|
|
||||||
# Transmit the games.
|
# Transmit the games.
|
||||||
for game in gamedb.getGames():
|
for game in games:
|
||||||
logging.debug(" %s" % game)
|
logging.debug(" %s" % game)
|
||||||
protocol.encodeMultiple(gamedb.getGames(), self.wfile)
|
protocol.encodeMultiple(games, self.wfile)
|
||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
logging.error("(%s) Unhandled exception: %s" % (gameHost, traceback.format_exc()))
|
logging.error("(%s) Unhandled exception: %s" % (gameHost, traceback.format_exc()))
|
||||||
|
|
Loading…
Reference in New Issue