From 9933b219a99f7935e301293854ce58781d0ad64e Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Sun, 17 Apr 2011 16:31:03 +0200 Subject: [PATCH] game list mutex in S_PH --- common/server_player.cpp | 1 + common/server_protocolhandler.cpp | 19 ++++++++++++++++--- common/server_protocolhandler.h | 2 ++ servatrice/src/serversocketinterface.cpp | 4 ++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/common/server_player.cpp b/common/server_player.cpp index 77c37622..f71c4cd5 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -18,6 +18,7 @@ Server_Player::Server_Player(Server_Game *_game, int _playerId, ServerInfo_User Server_Player::~Server_Player() { QMutexLocker locker(&game->gameMutex); + QMutexLocker locker2(&playerMutex); delete deck; diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index ab81a2c2..05ef513b 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -14,7 +14,7 @@ #include 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())); } @@ -35,6 +35,7 @@ void Server_ProtocolHandler::prepareDestroy() while (roomIterator.hasNext()) roomIterator.next().value()->removeClient(this); + gameListMutex.lock(); QMapIterator > gameIterator(games); while (gameIterator.hasNext()) { gameIterator.next(); @@ -46,6 +47,7 @@ void Server_ProtocolHandler::prepareDestroy() else p->setProtocolHandler(0); } + gameListMutex.unlock(); delete userInfo; QMapIterator i(buddyList); @@ -59,6 +61,8 @@ void Server_ProtocolHandler::prepareDestroy() void Server_ProtocolHandler::playerRemovedFromGame(Server_Game *game) { qDebug() << "Server_ProtocolHandler::playerRemovedFromGame(): gameId =" << game->getGameId(); + + QMutexLocker locker(&gameListMutex); games.remove(game->getGameId()); } @@ -89,7 +93,8 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm qDebug() << "received GameCommand: game =" << gameCommand->getGameId(); if (authState == PasswordWrong) return RespLoginNeeded; - + + gameListMutex.lock(); if (!games.contains(gameCommand->getGameId())) { qDebug() << "invalid game"; return RespNameNotFound; @@ -99,6 +104,7 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm Server_Player *player = gamePair.second; QMutexLocker locker(&game->gameMutex); + gameListMutex.unlock(); switch (command->getItemId()) { case ItemId_Command_DeckSelect: return cmdDeckSelect(static_cast(command), cont, game, player); @@ -181,7 +187,8 @@ void Server_ProtocolHandler::processCommandContainer(CommandContainer *cont) ProtocolResponse *pr = cont->getResponse(); if (!pr) pr = new ProtocolResponse(cont->getCmdId(), finalResponseCode); - + + gameListMutex.lock(); GameEventContainer *gQPublic = cont->getGameEventQueuePublic(); if (gQPublic) { Server_Game *game = games.value(gQPublic->getGameId()).first; @@ -204,6 +211,7 @@ void Server_ProtocolHandler::processCommandContainer(CommandContainer *cont) } else game->sendGameEventContainer(gQPublic); } + gameListMutex.unlock(); const QList &iQ = cont->getItemQueue(); 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. QMutexLocker serverLocker(&server->serverMutex); + QMutexLocker gameListLocker(&gameListMutex); const QList &serverGames = server->getGames(); for (int i = 0; i < serverGames.size(); ++i) { 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_Player *creator = game->getPlayers().values().first(); + + QMutexLocker gameListLocker(&gameListMutex); games.insert(game->getGameId(), QPair(game, creator)); 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) return RespLoginNeeded; + QMutexLocker gameListLocker(&gameListMutex); + if (games.contains(cmd->getGameId())) return RespContextError; diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index 8e671ce5..c65d8d02 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -94,6 +94,8 @@ private: private slots: void pingClockTimeout(); public: + QMutex gameListMutex; + Server_ProtocolHandler(Server *_server, QObject *parent = 0); ~Server_ProtocolHandler(); void playerRemovedFromGame(Server_Game *game); diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 835e9a11..79ef89ea 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -63,13 +63,13 @@ ServerSocketInterface::~ServerSocketInterface() QMutexLocker locker(&servatrice->serverMutex); logger->logMessage("ServerSocketInterface destructor"); + prepareDestroy(); + flushXmlBuffer(); delete xmlWriter; delete xmlReader; delete socket; socket = 0; - - prepareDestroy(); } void ServerSocketInterface::processProtocolItem(ProtocolItem *item)