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 struct
import socket
from threading import Lock, Thread, Event, Timer
from threading import Lock, RLock, Thread, Event, Timer
from select import select
import logging
import traceback
@ -64,13 +64,11 @@ logging.basicConfig(level = logging.DEBUG, format = "%(asctime)-15s %(levelname)
# Game DB
gamedb = None
gamedblock = Lock()
class GameDB:
global gamedblock
def __init__(self):
self.list = set()
self.lock = RLock()
def __remove(self, g):
# if g is not in the list, ignore the KeyError exception
@ -81,41 +79,47 @@ class GameDB:
def addGame(self, g):
""" add a game """
with gamedblock:
with self.lock:
self.list.add(g)
def removeGame(self, g):
""" remove a game from the list"""
with gamedblock:
with self.lock:
self.__remove(g)
# only games with a valid description
def getGames(self):
""" 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):
""" return all knwon games """
return self.list
with self.lock:
for game in self.list:
yield game
def getGamesByHost(self, 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):
with gamedblock:
gamesCount = len(self.getGames())
logging.debug("Checking: %i game(s)" % (gamesCount))
for game in self.getGames():
with self.lock:
games = list(self.getGames())
logging.debug("Checking: %i game(s)" % (len(games)))
for game in games:
if not protocol.check(game):
logging.debug("Removing unreachable game: %s" % game)
self.__remove(game)
def listGames(self):
with gamedblock:
gamesCount = len(self.getGames())
logging.debug("Gameserver list: %i game(s)" % (gamesCount))
for game in self.getGames():
with self.lock:
games = list(self.getGames())
logging.debug("Gameserver list: %i game(s)" % (len(games)))
for game in games:
logging.debug(" %s" % game)
#
@ -200,15 +204,15 @@ class RequestHandler(SocketServer.ThreadingMixIn, SocketServer.StreamRequestHand
# Get a game list.
elif netCommand == 'list':
# Lock the gamelist to prevent new games while output.
with gamedblock:
with gamedb.lock:
try:
gamesCount = len(gamedb.getGames())
logging.debug("(%s) Gameserver list: %i game(s)" % (gameHost, gamesCount))
games = list(gamedb.getGames())
logging.debug("(%s) Gameserver list: %i game(s)" % (gameHost, len(games)))
# Transmit the games.
for game in gamedb.getGames():
for game in games:
logging.debug(" %s" % game)
protocol.encodeMultiple(gamedb.getGames(), self.wfile)
protocol.encodeMultiple(games, self.wfile)
break
except:
logging.error("(%s) Unhandled exception: %s" % (gameHost, traceback.format_exc()))