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-861f7616d084
master
Giel van Schijndel 2009-05-01 22:02:08 +00:00 committed by Git SVN Gateway
parent 3153a9f63d
commit 0c7f44ee70
1 changed files with 26 additions and 22 deletions

View File

@ -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()))