Debugger: Fix lock when profiling
authorKai Koehne <kai.koehne@nokia.com>
Thu, 6 Oct 2011 14:33:47 +0000 (16:33 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 7 Oct 2011 16:42:13 +0000 (18:42 +0200)
Parts of the loading of data is now in a separate thread, which was already
trying to log trace data while the QDeclarativeDebugTrace constructor
was still blocking. Avoid this by calling QDeclarativeDebugTrace constructor
before the actual execution begins (addEngine()). Also make sure that the
logging methods are reentrant with a mutex.

Change-Id: I5c2c1d14763fd9c7cb6fc93c6dff22d00d8737f1
Reviewed-on: http://codereview.qt-project.org/6169
Reviewed-by: Christiaan Janssen <christiaan.janssen@nokia.com>
Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com>

src/declarative/debugger/qdeclarativedebugtrace.cpp
src/declarative/debugger/qdeclarativedebugtrace_p.h
src/declarative/qml/qdeclarativeengine.cpp

index befc3ea..76e4e23 100644 (file)
@@ -44,6 +44,8 @@
 #include <QtCore/qdatastream.h>
 #include <QtCore/qurl.h>
 #include <QtCore/qtimer.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qcoreapplication.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -77,6 +79,16 @@ QDeclarativeDebugTrace::QDeclarativeDebugTrace()
     }
 }
 
+void QDeclarativeDebugTrace::addEngine(QDeclarativeEngine * /*engine*/)
+{
+    // just make sure that the service is properly registered
+    traceInstance();
+}
+
+void QDeclarativeDebugTrace::removeEngine(QDeclarativeEngine */*engine*/)
+{
+}
+
 void QDeclarativeDebugTrace::addEvent(EventType t)
 {
     if (QDeclarativeDebugService::isDebuggingEnabled())
@@ -188,7 +200,9 @@ void QDeclarativeDebugTrace::endRangeImpl(RangeType range)
 */
 void QDeclarativeDebugTrace::processMessage(const QDeclarativeDebugData &message)
 {
-    if (m_deferredSend)
+    QMutexLocker locker(&m_mutex);
+    if (m_deferredSend
+            || (QThread::currentThread() != QCoreApplication::instance()->thread()))
         m_data.append(message);
     else
         sendMessage(message.toByteArray());
@@ -200,6 +214,7 @@ void QDeclarativeDebugTrace::processMessage(const QDeclarativeDebugData &message
 void QDeclarativeDebugTrace::sendMessages()
 {
     if (m_deferredSend) {
+        QMutexLocker locker(&m_mutex);
         //### this is a suboptimal way to send batched messages
         for (int i = 0; i < m_data.count(); ++i)
             sendMessage(m_data.at(i).toByteArray());
index fb2ef53..06c4311 100644 (file)
@@ -55,6 +55,7 @@
 
 #include <private/qdeclarativedebugservice_p.h>
 #include <QtCore/qelapsedtimer.h>
+#include <QtCore/qmutex.h>
 
 QT_BEGIN_HEADER
 
@@ -74,6 +75,8 @@ struct QDeclarativeDebugData
 };
 
 class QUrl;
+class QDeclarativeEngine;
+
 class Q_DECLARATIVE_EXPORT QDeclarativeDebugTrace : public QDeclarativeDebugService
 {
 public:
@@ -106,6 +109,9 @@ public:
         MaximumRangeType
     };
 
+    static void addEngine(QDeclarativeEngine *engine);
+    static void removeEngine(QDeclarativeEngine *engine);
+
     static void addEvent(EventType);
 
     static void startRange(RangeType);
@@ -133,6 +139,7 @@ private:
     bool m_deferredSend;
     bool m_messageReceived;
     QList<QDeclarativeDebugData> m_data;
+    QMutex m_mutex;
 };
 
 QT_END_NAMESPACE
index 2b76f1f..1794dbe 100644 (file)
@@ -438,6 +438,7 @@ void QDeclarativeEnginePrivate::init()
         QDeclarativeEngineDebugService::instance()->addEngine(q);
         QV8DebugService::instance()->addEngine(q);
         QV8ProfilerService::instance()->addEngine(q);
+        QDeclarativeDebugTrace::addEngine(q);
     }
 }
 
@@ -504,6 +505,7 @@ QDeclarativeEngine::~QDeclarativeEngine()
         QDeclarativeEngineDebugService::instance()->remEngine(this);
         QV8DebugService::instance()->removeEngine(this);
         QV8ProfilerService::instance()->removeEngine(this);
+        QDeclarativeDebugTrace::removeEngine(this);
     }
 
     // if we are the parent of any of the qobject module api instances,