game list mutex in S_PH

This commit is contained in:
Max-Wilhelm Bruker 2011-04-17 16:31:03 +02:00
parent 2d8b12a576
commit 9933b219a9
4 changed files with 21 additions and 5 deletions

View file

@ -18,6 +18,7 @@ Server_Player::Server_Player(Server_Game *_game, int _playerId, ServerInfo_User
Server_Player::~Server_Player() Server_Player::~Server_Player()
{ {
QMutexLocker locker(&game->gameMutex); QMutexLocker locker(&game->gameMutex);
QMutexLocker locker2(&playerMutex);
delete deck; delete deck;

View file

@ -14,7 +14,7 @@
#include <QDateTime> #include <QDateTime>
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent) Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
: QObject(parent), server(_server), authState(PasswordWrong), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), timeRunning(0), lastDataReceived(0) : QObject(parent), server(_server), authState(PasswordWrong), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), timeRunning(0), lastDataReceived(0), gameListMutex(QMutex::Recursive)
{ {
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout())); connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
} }
@ -35,6 +35,7 @@ void Server_ProtocolHandler::prepareDestroy()
while (roomIterator.hasNext()) while (roomIterator.hasNext())
roomIterator.next().value()->removeClient(this); roomIterator.next().value()->removeClient(this);
gameListMutex.lock();
QMapIterator<int, QPair<Server_Game *, Server_Player *> > gameIterator(games); QMapIterator<int, QPair<Server_Game *, Server_Player *> > gameIterator(games);
while (gameIterator.hasNext()) { while (gameIterator.hasNext()) {
gameIterator.next(); gameIterator.next();
@ -46,6 +47,7 @@ void Server_ProtocolHandler::prepareDestroy()
else else
p->setProtocolHandler(0); p->setProtocolHandler(0);
} }
gameListMutex.unlock();
delete userInfo; delete userInfo;
QMapIterator<QString, ServerInfo_User *> i(buddyList); QMapIterator<QString, ServerInfo_User *> i(buddyList);
@ -59,6 +61,8 @@ void Server_ProtocolHandler::prepareDestroy()
void Server_ProtocolHandler::playerRemovedFromGame(Server_Game *game) void Server_ProtocolHandler::playerRemovedFromGame(Server_Game *game)
{ {
qDebug() << "Server_ProtocolHandler::playerRemovedFromGame(): gameId =" << game->getGameId(); qDebug() << "Server_ProtocolHandler::playerRemovedFromGame(): gameId =" << game->getGameId();
QMutexLocker locker(&gameListMutex);
games.remove(game->getGameId()); games.remove(game->getGameId());
} }
@ -89,7 +93,8 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm
qDebug() << "received GameCommand: game =" << gameCommand->getGameId(); qDebug() << "received GameCommand: game =" << gameCommand->getGameId();
if (authState == PasswordWrong) if (authState == PasswordWrong)
return RespLoginNeeded; return RespLoginNeeded;
gameListMutex.lock();
if (!games.contains(gameCommand->getGameId())) { if (!games.contains(gameCommand->getGameId())) {
qDebug() << "invalid game"; qDebug() << "invalid game";
return RespNameNotFound; return RespNameNotFound;
@ -99,6 +104,7 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm
Server_Player *player = gamePair.second; Server_Player *player = gamePair.second;
QMutexLocker locker(&game->gameMutex); QMutexLocker locker(&game->gameMutex);
gameListMutex.unlock();
switch (command->getItemId()) { switch (command->getItemId()) {
case ItemId_Command_DeckSelect: return cmdDeckSelect(static_cast<Command_DeckSelect *>(command), cont, game, player); case ItemId_Command_DeckSelect: return cmdDeckSelect(static_cast<Command_DeckSelect *>(command), cont, game, player);
@ -181,7 +187,8 @@ void Server_ProtocolHandler::processCommandContainer(CommandContainer *cont)
ProtocolResponse *pr = cont->getResponse(); ProtocolResponse *pr = cont->getResponse();
if (!pr) if (!pr)
pr = new ProtocolResponse(cont->getCmdId(), finalResponseCode); pr = new ProtocolResponse(cont->getCmdId(), finalResponseCode);
gameListMutex.lock();
GameEventContainer *gQPublic = cont->getGameEventQueuePublic(); GameEventContainer *gQPublic = cont->getGameEventQueuePublic();
if (gQPublic) { if (gQPublic) {
Server_Game *game = games.value(gQPublic->getGameId()).first; Server_Game *game = games.value(gQPublic->getGameId()).first;
@ -204,6 +211,7 @@ void Server_ProtocolHandler::processCommandContainer(CommandContainer *cont)
} else } else
game->sendGameEventContainer(gQPublic); game->sendGameEventContainer(gQPublic);
} }
gameListMutex.unlock();
const QList<ProtocolItem *> &iQ = cont->getItemQueue(); const QList<ProtocolItem *> &iQ = cont->getItemQueue();
for (int i = 0; i < iQ.size(); ++i) for (int i = 0; i < iQ.size(); ++i)
@ -273,6 +281,7 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain
// This might not scale very well. Use an extra QMap if it becomes a problem. // This might not scale very well. Use an extra QMap if it becomes a problem.
QMutexLocker serverLocker(&server->serverMutex); QMutexLocker serverLocker(&server->serverMutex);
QMutexLocker gameListLocker(&gameListMutex);
const QList<Server_Game *> &serverGames = server->getGames(); const QList<Server_Game *> &serverGames = server->getGames();
for (int i = 0; i < serverGames.size(); ++i) { for (int i = 0; i < serverGames.size(); ++i) {
QMutexLocker gameLocker(&serverGames[i]->gameMutex); QMutexLocker gameLocker(&serverGames[i]->gameMutex);
@ -435,6 +444,8 @@ ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, Comm
Server_Game *game = room->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), gameTypes, cmd->getOnlyBuddies(), cmd->getOnlyRegistered(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this); Server_Game *game = room->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), gameTypes, cmd->getOnlyBuddies(), cmd->getOnlyRegistered(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this);
Server_Player *creator = game->getPlayers().values().first(); Server_Player *creator = game->getPlayers().values().first();
QMutexLocker gameListLocker(&gameListMutex);
games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, creator)); games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, creator));
sendProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), creator->getPlayerId(), false, game->getSpectatorsCanTalk(), game->getSpectatorsSeeEverything(), false)); sendProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), creator->getPlayerId(), false, game->getSpectatorsCanTalk(), game->getSpectatorsSeeEverything(), false));
@ -450,6 +461,8 @@ ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandC
if (authState == PasswordWrong) if (authState == PasswordWrong)
return RespLoginNeeded; return RespLoginNeeded;
QMutexLocker gameListLocker(&gameListMutex);
if (games.contains(cmd->getGameId())) if (games.contains(cmd->getGameId()))
return RespContextError; return RespContextError;

View file

@ -94,6 +94,8 @@ private:
private slots: private slots:
void pingClockTimeout(); void pingClockTimeout();
public: public:
QMutex gameListMutex;
Server_ProtocolHandler(Server *_server, QObject *parent = 0); Server_ProtocolHandler(Server *_server, QObject *parent = 0);
~Server_ProtocolHandler(); ~Server_ProtocolHandler();
void playerRemovedFromGame(Server_Game *game); void playerRemovedFromGame(Server_Game *game);

View file

@ -63,13 +63,13 @@ ServerSocketInterface::~ServerSocketInterface()
QMutexLocker locker(&servatrice->serverMutex); QMutexLocker locker(&servatrice->serverMutex);
logger->logMessage("ServerSocketInterface destructor"); logger->logMessage("ServerSocketInterface destructor");
prepareDestroy();
flushXmlBuffer(); flushXmlBuffer();
delete xmlWriter; delete xmlWriter;
delete xmlReader; delete xmlReader;
delete socket; delete socket;
socket = 0; socket = 0;
prepareDestroy();
} }
void ServerSocketInterface::processProtocolItem(ProtocolItem *item) void ServerSocketInterface::processProtocolItem(ProtocolItem *item)