more mutexes

This commit is contained in:
Max-Wilhelm Bruker 2011-03-22 19:37:56 +01:00
parent 4548841a93
commit 81a5d58d70
10 changed files with 127 additions and 7 deletions

View file

@ -23,6 +23,7 @@
#include "rng_abstract.h" #include "rng_abstract.h"
#include <QSet> #include <QSet>
#include <QDebug> #include <QDebug>
#include "server_game.h"
Server_CardZone::Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ZoneType _type) Server_CardZone::Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ZoneType _type)
: player(_player), name(_name), has_coords(_has_coords), type(_type), cardsBeingLookedAt(0) : player(_player), name(_name), has_coords(_has_coords), type(_type), cardsBeingLookedAt(0)
@ -37,6 +38,8 @@ Server_CardZone::~Server_CardZone()
void Server_CardZone::shuffle() void Server_CardZone::shuffle()
{ {
QMutexLocker locker(&player->getGame()->gameMutex);
QList<Server_Card *> temp; QList<Server_Card *> temp;
for (int i = cards.size(); i; i--) for (int i = cards.size(); i; i--)
temp.append(cards.takeAt(rng->getNumber(0, i - 1))); temp.append(cards.takeAt(rng->getNumber(0, i - 1)));
@ -45,6 +48,8 @@ void Server_CardZone::shuffle()
int Server_CardZone::removeCard(Server_Card *card) int Server_CardZone::removeCard(Server_Card *card)
{ {
QMutexLocker locker(&player->getGame()->gameMutex);
int index = cards.indexOf(card); int index = cards.indexOf(card);
cards.removeAt(index); cards.removeAt(index);
return index; return index;
@ -52,6 +57,8 @@ int Server_CardZone::removeCard(Server_Card *card)
Server_Card *Server_CardZone::getCard(int id, bool remove, int *position) Server_Card *Server_CardZone::getCard(int id, bool remove, int *position)
{ {
QMutexLocker locker(&player->getGame()->gameMutex);
if (type != HiddenZone) { if (type != HiddenZone) {
QListIterator<Server_Card *> CardIterator(cards); QListIterator<Server_Card *> CardIterator(cards);
int i = 0; int i = 0;
@ -85,6 +92,8 @@ Server_Card *Server_CardZone::getCard(int id, bool remove, int *position)
int Server_CardZone::getFreeGridColumn(int x, int y, const QString &cardName) const int Server_CardZone::getFreeGridColumn(int x, int y, const QString &cardName) const
{ {
QMutexLocker locker(&player->getGame()->gameMutex);
QMap<int, Server_Card *> coordMap; QMap<int, Server_Card *> coordMap;
for (int i = 0; i < cards.size(); ++i) for (int i = 0; i < cards.size(); ++i)
if (cards[i]->getY() == y) if (cards[i]->getY() == y)
@ -131,6 +140,8 @@ bool Server_CardZone::isColumnStacked(int x, int y) const
if (!has_coords) if (!has_coords)
return false; return false;
QMutexLocker locker(&player->getGame()->gameMutex);
QMap<int, Server_Card *> coordMap; QMap<int, Server_Card *> coordMap;
for (int i = 0; i < cards.size(); ++i) for (int i = 0; i < cards.size(); ++i)
if (cards[i]->getY() == y) if (cards[i]->getY() == y)
@ -144,6 +155,8 @@ bool Server_CardZone::isColumnEmpty(int x, int y) const
if (!has_coords) if (!has_coords)
return true; return true;
QMutexLocker locker(&player->getGame()->gameMutex);
QMap<int, Server_Card *> coordMap; QMap<int, Server_Card *> coordMap;
for (int i = 0; i < cards.size(); ++i) for (int i = 0; i < cards.size(); ++i)
if (cards[i]->getY() == y) if (cards[i]->getY() == y)
@ -154,6 +167,8 @@ bool Server_CardZone::isColumnEmpty(int x, int y) const
void Server_CardZone::moveCard(CommandContainer *cont, QMap<int, Server_Card *> &coordMap, Server_Card *card, int x, int y) void Server_CardZone::moveCard(CommandContainer *cont, QMap<int, Server_Card *> &coordMap, Server_Card *card, int x, int y)
{ {
QMutexLocker locker(&player->getGame()->gameMutex);
coordMap.remove(card->getY() * 10000 + card->getX()); coordMap.remove(card->getY() * 10000 + card->getX());
CardToMove *cardToMove = new CardToMove(card->getId()); CardToMove *cardToMove = new CardToMove(card->getId());
@ -165,6 +180,8 @@ void Server_CardZone::moveCard(CommandContainer *cont, QMap<int, Server_Card *>
void Server_CardZone::fixFreeSpaces(CommandContainer *cont) void Server_CardZone::fixFreeSpaces(CommandContainer *cont)
{ {
QMutexLocker locker(&player->getGame()->gameMutex);
QMap<int, Server_Card *> coordMap; QMap<int, Server_Card *> coordMap;
QSet<int> placesToLook; QSet<int> placesToLook;
for (int i = 0; i < cards.size(); ++i) { for (int i = 0; i < cards.size(); ++i) {
@ -194,6 +211,8 @@ void Server_CardZone::fixFreeSpaces(CommandContainer *cont)
void Server_CardZone::insertCard(Server_Card *card, int x, int y) void Server_CardZone::insertCard(Server_Card *card, int x, int y)
{ {
QMutexLocker locker(&player->getGame()->gameMutex);
if (hasCoords()) { if (hasCoords()) {
card->setCoords(x, y); card->setCoords(x, y);
cards.append(card); cards.append(card);
@ -206,6 +225,8 @@ void Server_CardZone::insertCard(Server_Card *card, int x, int y)
void Server_CardZone::clear() void Server_CardZone::clear()
{ {
QMutexLocker locker(&player->getGame()->gameMutex);
for (int i = 0; i < cards.size(); i++) for (int i = 0; i < cards.size(); i++)
delete cards.at(i); delete cards.at(i);
cards.clear(); cards.clear();

View file

@ -29,7 +29,7 @@
#include <QDebug> #include <QDebug>
Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList<int> &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent) Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList<int> &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent)
: QObject(parent), creatorInfo(new ServerInfo_User(_creator->getUserInfo())), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), gameTypes(_gameTypes), activePlayer(-1), activePhase(-1), onlyBuddies(_onlyBuddies), onlyRegistered(_onlyRegistered), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0), secondsElapsed(0) : QObject(parent), creatorInfo(new ServerInfo_User(_creator->getUserInfo())), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), gameTypes(_gameTypes), activePlayer(-1), activePhase(-1), onlyBuddies(_onlyBuddies), onlyRegistered(_onlyRegistered), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0), secondsElapsed(0), gameMutex(QMutex::Recursive)
{ {
addPlayer(_creator, false, false); addPlayer(_creator, false, false);
@ -42,6 +42,8 @@ Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QS
Server_Game::~Server_Game() Server_Game::~Server_Game()
{ {
QMutexLocker locker(&gameMutex);
sendGameEvent(new Event_GameClosed); sendGameEvent(new Event_GameClosed);
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
@ -56,6 +58,7 @@ Server_Game::~Server_Game()
void Server_Game::pingClockTimeout() void Server_Game::pingClockTimeout()
{ {
QMutexLocker locker(&gameMutex);
++secondsElapsed; ++secondsElapsed;
QList<ServerInfo_PlayerPing *> pingList; QList<ServerInfo_PlayerPing *> pingList;
@ -83,6 +86,8 @@ void Server_Game::pingClockTimeout()
int Server_Game::getPlayerCount() const int Server_Game::getPlayerCount() const
{ {
QMutexLocker locker(&gameMutex);
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
int result = 0; int result = 0;
while (playerIterator.hasNext()) while (playerIterator.hasNext())
@ -93,6 +98,8 @@ int Server_Game::getPlayerCount() const
int Server_Game::getSpectatorCount() const int Server_Game::getSpectatorCount() const
{ {
QMutexLocker locker(&gameMutex);
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
int result = 0; int result = 0;
while (playerIterator.hasNext()) while (playerIterator.hasNext())
@ -103,6 +110,8 @@ int Server_Game::getSpectatorCount() const
void Server_Game::startGameIfReady() void Server_Game::startGameIfReady()
{ {
QMutexLocker locker(&gameMutex);
if (getPlayerCount() < maxPlayers) if (getPlayerCount() < maxPlayers)
return; return;
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
@ -149,6 +158,8 @@ void Server_Game::startGameIfReady()
void Server_Game::stopGameIfFinished() void Server_Game::stopGameIfFinished()
{ {
QMutexLocker locker(&gameMutex);
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
int playing = 0; int playing = 0;
while (playerIterator.hasNext()) { while (playerIterator.hasNext()) {
@ -194,6 +205,8 @@ ResponseCode Server_Game::checkJoin(ServerInfo_User *user, const QString &_passw
Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spectator, bool broadcastUpdate) Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spectator, bool broadcastUpdate)
{ {
QMutexLocker locker(&gameMutex);
const QList<int> &keyList = players.keys(); const QList<int> &keyList = players.keys();
int playerId = keyList.isEmpty() ? 0 : (keyList.last() + 1); int playerId = keyList.isEmpty() ? 0 : (keyList.last() + 1);
@ -209,6 +222,8 @@ Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spec
void Server_Game::removePlayer(Server_Player *player) void Server_Game::removePlayer(Server_Player *player)
{ {
QMutexLocker locker(&gameMutex);
players.remove(player->getPlayerId()); players.remove(player->getPlayerId());
removeArrowsToPlayer(player); removeArrowsToPlayer(player);
@ -229,6 +244,8 @@ void Server_Game::removePlayer(Server_Player *player)
void Server_Game::removeArrowsToPlayer(Server_Player *player) void Server_Game::removeArrowsToPlayer(Server_Player *player)
{ {
QMutexLocker locker(&gameMutex);
// Remove all arrows of other players pointing to the player being removed or to one of his cards. // Remove all arrows of other players pointing to the player being removed or to one of his cards.
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) { while (playerIterator.hasNext()) {
@ -253,6 +270,8 @@ void Server_Game::removeArrowsToPlayer(Server_Player *player)
bool Server_Game::kickPlayer(int playerId) bool Server_Game::kickPlayer(int playerId)
{ {
QMutexLocker locker(&gameMutex);
Server_Player *playerToKick = players.value(playerId); Server_Player *playerToKick = players.value(playerId);
if (!playerToKick) if (!playerToKick)
return false; return false;
@ -265,6 +284,8 @@ bool Server_Game::kickPlayer(int playerId)
void Server_Game::setActivePlayer(int _activePlayer) void Server_Game::setActivePlayer(int _activePlayer)
{ {
QMutexLocker locker(&gameMutex);
activePlayer = _activePlayer; activePlayer = _activePlayer;
sendGameEvent(new Event_SetActivePlayer(activePlayer, activePlayer)); sendGameEvent(new Event_SetActivePlayer(activePlayer, activePlayer));
setActivePhase(0); setActivePhase(0);
@ -272,6 +293,8 @@ void Server_Game::setActivePlayer(int _activePlayer)
void Server_Game::setActivePhase(int _activePhase) void Server_Game::setActivePhase(int _activePhase)
{ {
QMutexLocker locker(&gameMutex);
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) { while (playerIterator.hasNext()) {
Server_Player *player = playerIterator.next().value(); Server_Player *player = playerIterator.next().value();
@ -289,6 +312,8 @@ void Server_Game::setActivePhase(int _activePhase)
void Server_Game::nextTurn() void Server_Game::nextTurn()
{ {
QMutexLocker locker(&gameMutex);
const QList<int> keys = players.keys(); const QList<int> keys = players.keys();
int listPos = -1; int listPos = -1;
if (activePlayer != -1) if (activePlayer != -1)
@ -304,6 +329,8 @@ void Server_Game::nextTurn()
QList<ServerInfo_Player *> Server_Game::getGameState(Server_Player *playerWhosAsking) const QList<ServerInfo_Player *> Server_Game::getGameState(Server_Player *playerWhosAsking) const
{ {
QMutexLocker locker(&gameMutex);
QList<ServerInfo_Player *> result; QList<ServerInfo_Player *> result;
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) { while (playerIterator.hasNext()) {
@ -392,6 +419,8 @@ void Server_Game::sendGameEvent(GameEvent *event, GameEventContext *context, Ser
void Server_Game::sendGameEventContainer(GameEventContainer *cont, Server_Player *exclude, bool excludeOmniscient) void Server_Game::sendGameEventContainer(GameEventContainer *cont, Server_Player *exclude, bool excludeOmniscient)
{ {
QMutexLocker locker(&gameMutex);
cont->setGameId(gameId); cont->setGameId(gameId);
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) { while (playerIterator.hasNext()) {
@ -405,6 +434,8 @@ void Server_Game::sendGameEventContainer(GameEventContainer *cont, Server_Player
void Server_Game::sendGameEventContainerOmniscient(GameEventContainer *cont, Server_Player *exclude) void Server_Game::sendGameEventContainerOmniscient(GameEventContainer *cont, Server_Player *exclude)
{ {
QMutexLocker locker(&gameMutex);
cont->setGameId(gameId); cont->setGameId(gameId);
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) { while (playerIterator.hasNext()) {
@ -423,6 +454,8 @@ void Server_Game::sendGameEventToPlayer(Server_Player *player, GameEvent *event)
ServerInfo_Game *Server_Game::getInfo() const ServerInfo_Game *Server_Game::getInfo() const
{ {
QMutexLocker locker(&gameMutex);
if (players.isEmpty()) if (players.isEmpty())
// Game is closing // Game is closing
return new ServerInfo_Game(getGameId(), QString(), false, 0, getMaxPlayers(), QList<GameTypeId *>(), 0, false, 0); return new ServerInfo_Game(getGameId(), QString(), false, 0, getMaxPlayers(), QList<GameTypeId *>(), 0, false, 0);

View file

@ -23,6 +23,7 @@
#include <QStringList> #include <QStringList>
#include <QPointer> #include <QPointer>
#include <QObject> #include <QObject>
#include <QMutex>
#include "server_player.h" #include "server_player.h"
#include "protocol.h" #include "protocol.h"
@ -55,6 +56,7 @@ signals:
private slots: private slots:
void pingClockTimeout(); void pingClockTimeout();
public: public:
mutable QMutex gameMutex;
Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList<int> &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent); Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList<int> &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent);
~Server_Game(); ~Server_Game();
ServerInfo_Game *getInfo() const; ServerInfo_Game *getInfo() const;

View file

@ -17,6 +17,8 @@ Server_Player::Server_Player(Server_Game *_game, int _playerId, ServerInfo_User
Server_Player::~Server_Player() Server_Player::~Server_Player()
{ {
QMutexLocker locker(&game->gameMutex);
delete deck; delete deck;
if (handler) if (handler)
@ -28,11 +30,15 @@ Server_Player::~Server_Player()
int Server_Player::newCardId() int Server_Player::newCardId()
{ {
QMutexLocker locker(&game->gameMutex);
return nextCardId++; return nextCardId++;
} }
int Server_Player::newCounterId() const int Server_Player::newCounterId() const
{ {
QMutexLocker locker(&game->gameMutex);
int id = 0; int id = 0;
QMapIterator<int, Server_Counter *> i(counters); QMapIterator<int, Server_Counter *> i(counters);
while (i.hasNext()) { while (i.hasNext()) {
@ -45,6 +51,8 @@ int Server_Player::newCounterId() const
int Server_Player::newArrowId() const int Server_Player::newArrowId() const
{ {
QMutexLocker locker(&game->gameMutex);
int id = 0; int id = 0;
QMapIterator<int, Server_Arrow *> i(arrows); QMapIterator<int, Server_Arrow *> i(arrows);
while (i.hasNext()) { while (i.hasNext()) {
@ -57,6 +65,8 @@ int Server_Player::newArrowId() const
void Server_Player::setupZones() void Server_Player::setupZones()
{ {
QMutexLocker locker(&game->gameMutex);
// This may need to be customized according to the game rules. // This may need to be customized according to the game rules.
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@ -138,6 +148,8 @@ void Server_Player::setupZones()
void Server_Player::clearZones() void Server_Player::clearZones()
{ {
QMutexLocker locker(&game->gameMutex);
QMapIterator<QString, Server_CardZone *> zoneIterator(zones); QMapIterator<QString, Server_CardZone *> zoneIterator(zones);
while (zoneIterator.hasNext()) while (zoneIterator.hasNext())
delete zoneIterator.next().value(); delete zoneIterator.next().value();
@ -158,11 +170,15 @@ void Server_Player::clearZones()
ServerInfo_PlayerProperties *Server_Player::getProperties() ServerInfo_PlayerProperties *Server_Player::getProperties()
{ {
QMutexLocker locker(&game->gameMutex);
return new ServerInfo_PlayerProperties(playerId, new ServerInfo_User(userInfo), spectator, conceded, readyStart, deckId); return new ServerInfo_PlayerProperties(playerId, new ServerInfo_User(userInfo), spectator, conceded, readyStart, deckId);
} }
void Server_Player::setDeck(DeckList *_deck, int _deckId) void Server_Player::setDeck(DeckList *_deck, int _deckId)
{ {
QMutexLocker locker(&game->gameMutex);
delete deck; delete deck;
deck = _deck; deck = _deck;
deckId = _deckId; deckId = _deckId;
@ -170,16 +186,22 @@ void Server_Player::setDeck(DeckList *_deck, int _deckId)
void Server_Player::addZone(Server_CardZone *zone) void Server_Player::addZone(Server_CardZone *zone)
{ {
QMutexLocker locker(&game->gameMutex);
zones.insert(zone->getName(), zone); zones.insert(zone->getName(), zone);
} }
void Server_Player::addArrow(Server_Arrow *arrow) void Server_Player::addArrow(Server_Arrow *arrow)
{ {
QMutexLocker locker(&game->gameMutex);
arrows.insert(arrow->getId(), arrow); arrows.insert(arrow->getId(), arrow);
} }
bool Server_Player::deleteArrow(int arrowId) bool Server_Player::deleteArrow(int arrowId)
{ {
QMutexLocker locker(&game->gameMutex);
Server_Arrow *arrow = arrows.value(arrowId, 0); Server_Arrow *arrow = arrows.value(arrowId, 0);
if (!arrow) if (!arrow)
return false; return false;
@ -190,11 +212,15 @@ bool Server_Player::deleteArrow(int arrowId)
void Server_Player::addCounter(Server_Counter *counter) void Server_Player::addCounter(Server_Counter *counter)
{ {
QMutexLocker locker(&game->gameMutex);
counters.insert(counter->getId(), counter); counters.insert(counter->getId(), counter);
} }
bool Server_Player::deleteCounter(int counterId) bool Server_Player::deleteCounter(int counterId)
{ {
QMutexLocker locker(&game->gameMutex);
Server_Counter *counter = counters.value(counterId, 0); Server_Counter *counter = counters.value(counterId, 0);
if (!counter) if (!counter)
return false; return false;
@ -205,6 +231,8 @@ bool Server_Player::deleteCounter(int counterId)
ResponseCode Server_Player::drawCards(CommandContainer *cont, int number) ResponseCode Server_Player::drawCards(CommandContainer *cont, int number)
{ {
QMutexLocker locker(&game->gameMutex);
Server_CardZone *deckZone = zones.value("deck"); Server_CardZone *deckZone = zones.value("deck");
Server_CardZone *handZone = zones.value("hand"); Server_CardZone *handZone = zones.value("hand");
if (deckZone->cards.size() < number) if (deckZone->cards.size() < number)
@ -228,6 +256,8 @@ ResponseCode Server_Player::drawCards(CommandContainer *cont, int number)
ResponseCode Server_Player::undoDraw(CommandContainer *cont) ResponseCode Server_Player::undoDraw(CommandContainer *cont)
{ {
QMutexLocker locker(&game->gameMutex);
if (lastDrawList.isEmpty()) if (lastDrawList.isEmpty())
return RespContextError; return RespContextError;
@ -240,6 +270,8 @@ ResponseCode Server_Player::undoDraw(CommandContainer *cont)
ResponseCode Server_Player::moveCard(CommandContainer *cont, const QString &_startZone, const QList<CardToMove *> &_cards, int targetPlayerId, const QString &_targetZone, int x, int y, bool faceDown) ResponseCode Server_Player::moveCard(CommandContainer *cont, const QString &_startZone, const QList<CardToMove *> &_cards, int targetPlayerId, const QString &_targetZone, int x, int y, bool faceDown)
{ {
QMutexLocker locker(&game->gameMutex);
Server_CardZone *startzone = getZones().value(_startZone); Server_CardZone *startzone = getZones().value(_startZone);
Server_Player *targetPlayer = game->getPlayers().value(targetPlayerId); Server_Player *targetPlayer = game->getPlayers().value(targetPlayerId);
if (!targetPlayer) if (!targetPlayer)
@ -274,6 +306,8 @@ public:
ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *startzone, const QList<CardToMove *> &_cards, Server_CardZone *targetzone, int x, int y, bool faceDown, bool fixFreeSpaces, bool undoingDraw) ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *startzone, const QList<CardToMove *> &_cards, Server_CardZone *targetzone, int x, int y, bool faceDown, bool fixFreeSpaces, bool undoingDraw)
{ {
QMutexLocker locker(&game->gameMutex);
// Disallow controller change to other zones than the table. // Disallow controller change to other zones than the table.
if (((targetzone->getType() != PublicZone) || !targetzone->hasCoords()) && (startzone->getPlayer() != targetzone->getPlayer())) if (((targetzone->getType() != PublicZone) || !targetzone->hasCoords()) && (startzone->getPlayer() != targetzone->getPlayer()))
return RespContextError; return RespContextError;
@ -428,6 +462,8 @@ ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *st
void Server_Player::unattachCard(CommandContainer *cont, Server_Card *card) void Server_Player::unattachCard(CommandContainer *cont, Server_Card *card)
{ {
QMutexLocker locker(&game->gameMutex);
Server_CardZone *zone = card->getZone(); Server_CardZone *zone = card->getZone();
card->setParentCard(0); card->setParentCard(0);
@ -441,6 +477,8 @@ void Server_Player::unattachCard(CommandContainer *cont, Server_Card *card)
ResponseCode Server_Player::setCardAttrHelper(CommandContainer *cont, const QString &zoneName, int cardId, const QString &attrName, const QString &attrValue) ResponseCode Server_Player::setCardAttrHelper(CommandContainer *cont, const QString &zoneName, int cardId, const QString &attrName, const QString &attrValue)
{ {
QMutexLocker locker(&game->gameMutex);
Server_CardZone *zone = getZones().value(zoneName); Server_CardZone *zone = getZones().value(zoneName);
if (!zone) if (!zone)
return RespNameNotFound; return RespNameNotFound;
@ -471,6 +509,8 @@ ResponseCode Server_Player::setCardAttrHelper(CommandContainer *cont, const QStr
void Server_Player::sendProtocolItem(ProtocolItem *item, bool deleteItem) void Server_Player::sendProtocolItem(ProtocolItem *item, bool deleteItem)
{ {
QMutexLocker locker(&playerMutex);
if (handler) if (handler)
handler->sendProtocolItem(item, deleteItem); handler->sendProtocolItem(item, deleteItem);
} }

View file

@ -5,6 +5,7 @@
#include <QString> #include <QString>
#include <QList> #include <QList>
#include <QMap> #include <QMap>
#include <QMutex>
#include "protocol_datastructures.h" #include "protocol_datastructures.h"
class DeckList; class DeckList;
@ -22,6 +23,7 @@ class CommandContainer;
class Server_Player : public Server_ArrowTarget { class Server_Player : public Server_ArrowTarget {
Q_OBJECT Q_OBJECT
private: private:
mutable QMutex playerMutex;
class MoveCardCompareFunctor; class MoveCardCompareFunctor;
Server_Game *game; Server_Game *game;
Server_ProtocolHandler *handler; Server_ProtocolHandler *handler;
@ -42,7 +44,7 @@ public:
Server_Player(Server_Game *_game, int _playerId, ServerInfo_User *_userInfo, bool _spectator, Server_ProtocolHandler *_handler); Server_Player(Server_Game *_game, int _playerId, ServerInfo_User *_userInfo, bool _spectator, Server_ProtocolHandler *_handler);
~Server_Player(); ~Server_Player();
Server_ProtocolHandler *getProtocolHandler() const { return handler; } Server_ProtocolHandler *getProtocolHandler() const { return handler; }
void setProtocolHandler(Server_ProtocolHandler *_handler) { handler = _handler; } void setProtocolHandler(Server_ProtocolHandler *_handler) { playerMutex.lock(); handler = _handler; playerMutex.unlock(); }
void setPlayerId(int _id) { playerId = _id; } void setPlayerId(int _id) { playerId = _id; }
int getInitialCards() const { return initialCards; } int getInitialCards() const { return initialCards; }
@ -57,6 +59,7 @@ public:
ServerInfo_User *getUserInfo() const { return userInfo; } ServerInfo_User *getUserInfo() const { return userInfo; }
void setDeck(DeckList *_deck, int _deckId); void setDeck(DeckList *_deck, int _deckId);
DeckList *getDeck() const { return deck; } DeckList *getDeck() const { return deck; }
Server_Game *getGame() const { return game; }
const QMap<QString, Server_CardZone *> &getZones() const { return zones; } const QMap<QString, Server_CardZone *> &getZones() const { return zones; }
const QMap<int, Server_Counter *> &getCounters() const { return counters; } const QMap<int, Server_Counter *> &getCounters() const { return counters; }
const QMap<int, Server_Arrow *> &getArrows() const { return arrows; } const QMap<int, Server_Arrow *> &getArrows() const { return arrows; }

View file

@ -68,6 +68,8 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm
if (!room) if (!room)
return RespNameNotFound; return RespNameNotFound;
QMutexLocker locker(&room->roomMutex);
switch (command->getItemId()) { switch (command->getItemId()) {
case ItemId_Command_LeaveRoom: return cmdLeaveRoom(static_cast<Command_LeaveRoom *>(command), cont, room); case ItemId_Command_LeaveRoom: return cmdLeaveRoom(static_cast<Command_LeaveRoom *>(command), cont, room);
case ItemId_Command_RoomSay: return cmdRoomSay(static_cast<Command_RoomSay *>(command), cont, room); case ItemId_Command_RoomSay: return cmdRoomSay(static_cast<Command_RoomSay *>(command), cont, room);
@ -90,6 +92,8 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm
Server_Game *game = gamePair.first; Server_Game *game = gamePair.first;
Server_Player *player = gamePair.second; Server_Player *player = gamePair.second;
QMutexLocker locker(&game->gameMutex);
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);
case ItemId_Command_SetSideboardPlan: return cmdSetSideboardPlan(static_cast<Command_SetSideboardPlan *>(command), cont, game, player); case ItemId_Command_SetSideboardPlan: return cmdSetSideboardPlan(static_cast<Command_SetSideboardPlan *>(command), cont, game, player);

View file

@ -4,7 +4,7 @@
#include <QDebug> #include <QDebug>
Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent) Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent)
: QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes) : QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes), roomMutex(QMutex::Recursive)
{ {
connect(this, SIGNAL(sigCreateGame(const QString &, const QString &, int, const QList<int> &, bool, bool, bool, bool, bool, bool, Server_ProtocolHandler *)), this, SLOT(doCreateGame(const QString &, const QString &, int, const QList<int> &, bool, bool, bool, bool, bool, bool, Server_ProtocolHandler *))); connect(this, SIGNAL(sigCreateGame(const QString &, const QString &, int, const QList<int> &, bool, bool, bool, bool, bool, bool, Server_ProtocolHandler *)), this, SLOT(doCreateGame(const QString &, const QString &, int, const QList<int> &, bool, bool, bool, bool, bool, bool, Server_ProtocolHandler *)));
} }
@ -16,6 +16,8 @@ Server *Server_Room::getServer() const
ServerInfo_Room *Server_Room::getInfo(bool complete) const ServerInfo_Room *Server_Room::getInfo(bool complete) const
{ {
QMutexLocker locker(&roomMutex);
QList<ServerInfo_Game *> gameList; QList<ServerInfo_Game *> gameList;
QList<ServerInfo_User *> userList; QList<ServerInfo_User *> userList;
QList<ServerInfo_GameType *> gameTypeList; QList<ServerInfo_GameType *> gameTypeList;
@ -36,6 +38,8 @@ ServerInfo_Room *Server_Room::getInfo(bool complete) const
void Server_Room::addClient(Server_ProtocolHandler *client) void Server_Room::addClient(Server_ProtocolHandler *client)
{ {
QMutexLocker locker(&roomMutex);
sendRoomEvent(new Event_JoinRoom(id, new ServerInfo_User(client->getUserInfo(), false))); sendRoomEvent(new Event_JoinRoom(id, new ServerInfo_User(client->getUserInfo(), false)));
append(client); append(client);
emit roomInfoChanged(); emit roomInfoChanged();
@ -43,6 +47,8 @@ void Server_Room::addClient(Server_ProtocolHandler *client)
void Server_Room::removeClient(Server_ProtocolHandler *client) void Server_Room::removeClient(Server_ProtocolHandler *client)
{ {
QMutexLocker locker(&roomMutex);
removeAt(indexOf(client)); removeAt(indexOf(client));
sendRoomEvent(new Event_LeaveRoom(id, client->getUserInfo()->getName())); sendRoomEvent(new Event_LeaveRoom(id, client->getUserInfo()->getName()));
emit roomInfoChanged(); emit roomInfoChanged();
@ -55,6 +61,8 @@ void Server_Room::say(Server_ProtocolHandler *client, const QString &s)
void Server_Room::sendRoomEvent(RoomEvent *event) void Server_Room::sendRoomEvent(RoomEvent *event)
{ {
QMutexLocker locker(&roomMutex);
for (int i = 0; i < size(); ++i) for (int i = 0; i < size(); ++i)
at(i)->sendProtocolItem(event, false); at(i)->sendProtocolItem(event, false);
delete event; delete event;
@ -62,6 +70,8 @@ void Server_Room::sendRoomEvent(RoomEvent *event)
void Server_Room::broadcastGameListUpdate(Server_Game *game) void Server_Room::broadcastGameListUpdate(Server_Game *game)
{ {
QMutexLocker locker(&roomMutex);
Event_ListGames *event = new Event_ListGames(id, QList<ServerInfo_Game *>() << game->getInfo()); Event_ListGames *event = new Event_ListGames(id, QList<ServerInfo_Game *>() << game->getInfo());
for (int i = 0; i < size(); i++) for (int i = 0; i < size(); i++)
@ -71,6 +81,8 @@ void Server_Room::broadcastGameListUpdate(Server_Game *game)
void Server_Room::doCreateGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator) void Server_Room::doCreateGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator)
{ {
QMutexLocker locker(&roomMutex);
Server_Game *newGame = new Server_Game(creator, static_cast<Server *>(parent())->getNextGameId(), description, password, maxPlayers, gameTypes, onlyBuddies, onlyRegistered, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, this); Server_Game *newGame = new Server_Game(creator, static_cast<Server *>(parent())->getNextGameId(), description, password, maxPlayers, gameTypes, onlyBuddies, onlyRegistered, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, this);
games.insert(newGame->getGameId(), newGame); games.insert(newGame->getGameId(), newGame);
connect(newGame, SIGNAL(gameClosing()), this, SLOT(removeGame())); connect(newGame, SIGNAL(gameClosing()), this, SLOT(removeGame()));
@ -89,6 +101,8 @@ void Server_Room::createGame(const QString &description, const QString &password
void Server_Room::removeGame() void Server_Room::removeGame()
{ {
QMutexLocker locker(&roomMutex);
Server_Game *game = static_cast<Server_Game *>(sender()); Server_Game *game = static_cast<Server_Game *>(sender());
broadcastGameListUpdate(game); broadcastGameListUpdate(game);
games.remove(game->getGameId()); games.remove(game->getGameId());

View file

@ -5,6 +5,7 @@
#include <QMap> #include <QMap>
#include <QObject> #include <QObject>
#include <QStringList> #include <QStringList>
#include <QMutex>
class Server_ProtocolHandler; class Server_ProtocolHandler;
class RoomEvent; class RoomEvent;
@ -33,6 +34,7 @@ private slots:
void doCreateGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &_gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator); void doCreateGame(const QString &description, const QString &password, int maxPlayers, const QList<int> &_gameTypes, bool onlyBuddies, bool onlyRegistered, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator);
void removeGame(); void removeGame();
public: public:
mutable QMutex roomMutex;
Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent); Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent);
int getId() const { return id; } int getId() const { return id; }
QString getName() const { return name; } QString getName() const { return name; }

View file

@ -2,7 +2,6 @@
#include <QSocketNotifier> #include <QSocketNotifier>
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
#include <QMutex>
#include <QDateTime> #include <QDateTime>
#include <QThread> #include <QThread>
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
@ -34,11 +33,11 @@ void ServerLogger::logMessage(QString message)
if (!logFile) if (!logFile)
return; return;
static QMutex mutex; logFileMutex.lock();
mutex.lock();
QTextStream stream(logFile); QTextStream stream(logFile);
stream << QDateTime::currentDateTime().toString() << " " << ((void *) QThread::currentThread()) << " " << message << "\n"; stream << QDateTime::currentDateTime().toString() << " " << ((void *) QThread::currentThread()) << " " << message << "\n";
mutex.unlock(); stream.flush();
logFileMutex.unlock();
} }
void ServerLogger::hupSignalHandler(int /*unused*/) void ServerLogger::hupSignalHandler(int /*unused*/)

View file

@ -2,6 +2,7 @@
#define SERVER_LOGGER_H #define SERVER_LOGGER_H
#include <QObject> #include <QObject>
#include <QMutex>
class QSocketNotifier; class QSocketNotifier;
class QFile; class QFile;
@ -20,6 +21,7 @@ private:
static int sigHupFD[2]; static int sigHupFD[2];
QSocketNotifier *snHup; QSocketNotifier *snHup;
static QFile *logFile; static QFile *logFile;
QMutex logFileMutex;
}; };
#endif #endif