Merge pull request #2096 from ctrlaltca/fix_2091

Fix infinite loop on local game close
This commit is contained in:
ctrlaltca 2016-07-24 12:29:03 +02:00 committed by GitHub
commit 2cbfc5a8e6
3 changed files with 28 additions and 22 deletions

View file

@ -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();
}

View file

@ -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<int, Server_Room *> roomIterator(rooms);
while (roomIterator.hasNext())

View file

@ -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();
}