diff --git a/cockatrice/src/localserver.cpp b/cockatrice/src/localserver.cpp index c02a0562..e9035e82 100644 --- a/cockatrice/src/localserver.cpp +++ b/cockatrice/src/localserver.cpp @@ -11,6 +11,10 @@ LocalServer::LocalServer(QObject *parent) LocalServer::~LocalServer() { + // LocalServer is single threaded so it doesn't need locks on this + while (!clients.isEmpty()) + clients.first()->prepareDestroy(); + prepareDestroy(); } diff --git a/common/server.cpp b/common/server.cpp index df590227..768fb752 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -59,28 +59,6 @@ Server::~Server() void Server::prepareDestroy() { - // dirty :( - clientsLock.lockForRead(); - for (int i = 0; i < clients.size(); ++i) - QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection); - clientsLock.unlock(); - - bool done = false; - - class SleeperThread : public QThread - { - public: - static void msleep(unsigned long msecs) { QThread::usleep(msecs); } - }; - - do { - SleeperThread::msleep(10); - clientsLock.lockForRead(); - if (clients.isEmpty()) - done = true; - clientsLock.unlock(); - } while (!done); - roomsLock.lockForWrite(); QMapIterator roomIterator(rooms); while (roomIterator.hasNext()) diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index d215e053..32067065 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -181,6 +181,30 @@ Servatrice::Servatrice(QObject *parent) Servatrice::~Servatrice() { gameServer->close(); + + // clients live in other threads, we need to lock them + clientsLock.lockForRead(); + for (int i = 0; i < clients.size(); ++i) + QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection); + clientsLock.unlock(); + + // client destruction is asynchronous, wait for all clients to be gone + bool done = false; + + class SleeperThread : public QThread + { + public: + static void msleep(unsigned long msecs) { QThread::usleep(msecs); } + }; + + do { + SleeperThread::msleep(10); + clientsLock.lockForRead(); + if (clients.isEmpty()) + done = true; + clientsLock.unlock(); + } while (!done); + prepareDestroy(); }