Debugger: Fix livelock on exit (Windows)
authorKai Koehne <kai.koehne@nokia.com>
Tue, 20 Dec 2011 12:41:50 +0000 (13:41 +0100)
committerQt by Nokia <qt-info@nokia.com>
Tue, 20 Dec 2011 16:25:15 +0000 (17:25 +0100)
We used to close the debugger thread when the last service was killed: This happened
in the unloading of static global variables. Apparently this is too late on Windows,
since the OS thread associated was already terminated.

Instead, we now kill the instance when the QCoreApplication event loop is exiting.

Change-Id: I12a46ab9e7ac64561c94c0cd0d88b78fbaf8554c
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Reviewed-by: Aurindam Jana <aurindam.jana@nokia.com>
src/declarative/debugger/qdeclarativedebugserver.cpp
src/declarative/debugger/qdeclarativedebugserver_p.h

index 23f1e0d..df5c5f1 100644 (file)
@@ -231,6 +231,13 @@ bool QDeclarativeDebugServer::hasDebuggingClient() const
 
 static QDeclarativeDebugServer *qDeclarativeDebugServer = 0;
 
+
+static void cleanup()
+{
+    delete qDeclarativeDebugServer;
+    qDeclarativeDebugServer = 0;
+}
+
 QDeclarativeDebugServer *QDeclarativeDebugServer::instance()
 {
     static bool commandLineTested = false;
@@ -269,10 +276,7 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance()
 
             if (ok) {
                 qDeclarativeDebugServer = new QDeclarativeDebugServer();
-
                 QDeclarativeDebugServerThread *thread = new QDeclarativeDebugServerThread;
-
-                qDeclarativeDebugServer = new QDeclarativeDebugServer();
                 qDeclarativeDebugServer->d_func()->thread = thread;
                 qDeclarativeDebugServer->moveToThread(thread);
                 thread->setPluginName(pluginName);
@@ -309,6 +313,29 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance()
 QDeclarativeDebugServer::QDeclarativeDebugServer()
     : QObject(*(new QDeclarativeDebugServerPrivate))
 {
+    qAddPostRoutine(cleanup);
+}
+
+QDeclarativeDebugServer::~QDeclarativeDebugServer()
+{
+    Q_D(QDeclarativeDebugServer);
+
+    QReadLocker(&d->pluginsLock);
+    {
+        foreach (QDeclarativeDebugService *service, d->plugins.values()) {
+            service->d_func()->server = 0;
+            service->d_func()->status = QDeclarativeDebugService::NotConnected;
+            service->statusChanged(QDeclarativeDebugService::NotConnected);
+        }
+    }
+
+    if (d->thread) {
+        d->thread->exit();
+        if (!d->thread->wait(1000))
+            d->thread->terminate();
+        delete d->thread;
+    }
+    delete d->connection;
 }
 
 void QDeclarativeDebugServer::receiveMessage(const QByteArray &message)
@@ -463,17 +490,6 @@ bool QDeclarativeDebugServer::removeService(QDeclarativeDebugService *service)
         service->d_func()->server = 0;
         service->d_func()->status = newStatus;
         service->statusChanged(newStatus);
-
-        // Last service? Then stop thread & delete instance
-        if (d->plugins.isEmpty()) {
-            d->thread->exit();
-            d->thread->wait();
-            delete d->thread;
-            delete d->connection;
-
-            qDeclarativeDebugServer = 0;
-            deleteLater();
-        }
     }
 
     return true;
index 1333634..23a38b3 100644 (file)
@@ -71,6 +71,8 @@ class Q_DECLARATIVE_EXPORT QDeclarativeDebugServer : public QObject
     Q_DECLARE_PRIVATE(QDeclarativeDebugServer)
     Q_DISABLE_COPY(QDeclarativeDebugServer)
 public:
+    ~QDeclarativeDebugServer();
+
     static QDeclarativeDebugServer *instance();
 
     void setConnection(QDeclarativeDebugServerConnection *connection);