From 4cc230ade4df3919fbb9688b60e6e8f7f3cc8144 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 6 Feb 2014 14:43:26 +0100 Subject: Unify initial waiting of debug services The debug services generally behave in one of two ways when initializing: Either they block the initializing thread until some configuration is passed over the network or they just go on. By introducing a generalized configurable debug service the various ways of waiting on initialization are cleaned up. The API defined for it also allows for engine-specific initialization. Change-Id: Id5685ef17d2a7eb1222629f7caa5ec53076d47b2 Reviewed-by: Kai Koehne --- src/qml/debugger/debugger.pri | 7 +- src/qml/debugger/qqmlconfigurabledebugservice.cpp | 96 ++++++++++++++++++++++ src/qml/debugger/qqmlconfigurabledebugservice_p.h | 87 ++++++++++++++++++++ .../debugger/qqmlconfigurabledebugservice_p_p.h | 78 ++++++++++++++++++ src/qml/debugger/qqmldebugserver.cpp | 57 ++++++++++++- src/qml/debugger/qqmldebugserver_p.h | 3 + src/qml/debugger/qqmldebugservice.cpp | 6 +- src/qml/debugger/qqmldebugservice_p.h | 4 + src/qml/debugger/qqmlenginedebugservice.cpp | 2 + src/qml/debugger/qqmlprofilerservice.cpp | 29 ++----- src/qml/debugger/qqmlprofilerservice_p.h | 6 +- src/qml/debugger/qv4debugservice.cpp | 42 +++------- src/qml/debugger/qv4debugservice_p.h | 5 +- src/qml/debugger/qv4profilerservice.cpp | 26 ++---- src/qml/debugger/qv4profilerservice_p.h | 4 +- 15 files changed, 363 insertions(+), 89 deletions(-) create mode 100644 src/qml/debugger/qqmlconfigurabledebugservice.cpp create mode 100644 src/qml/debugger/qqmlconfigurabledebugservice_p.h create mode 100644 src/qml/debugger/qqmlconfigurabledebugservice_p_p.h diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri index 16785c48e3..2116c7292b 100644 --- a/src/qml/debugger/debugger.pri +++ b/src/qml/debugger/debugger.pri @@ -6,7 +6,8 @@ SOURCES += \ $$PWD/qv4profilerservice.cpp \ $$PWD/qqmlenginedebugservice.cpp \ $$PWD/qdebugmessageservice.cpp \ - $$PWD/qv4debugservice.cpp + $$PWD/qv4debugservice.cpp \ + $$PWD/qqmlconfigurabledebugservice.cpp HEADERS += \ $$PWD/qqmldebugservice_p.h \ @@ -21,4 +22,6 @@ HEADERS += \ $$PWD/qqmlenginedebugservice_p.h \ $$PWD/qqmldebug.h \ $$PWD/qdebugmessageservice_p.h \ - $$PWD/qv4debugservice_p.h + $$PWD/qv4debugservice_p.h \ + $$PWD/qqmlconfigurabledebugservice_p.h \ + $$PWD/qqmlconfigurabledebugservice_p_p.h diff --git a/src/qml/debugger/qqmlconfigurabledebugservice.cpp b/src/qml/debugger/qqmlconfigurabledebugservice.cpp new file mode 100644 index 0000000000..076e12b613 --- /dev/null +++ b/src/qml/debugger/qqmlconfigurabledebugservice.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqmlconfigurabledebugservice_p.h" +#include "qqmlconfigurabledebugservice_p_p.h" + +QT_BEGIN_NAMESPACE + +QQmlConfigurableDebugService::QQmlConfigurableDebugService(const QString &name, float version, + QObject *parent) : + QQmlDebugService((*new QQmlConfigurableDebugServicePrivate), name, version, parent) { init(); } + +QQmlConfigurableDebugService::QQmlConfigurableDebugService(QQmlDebugServicePrivate &dd, + const QString &name, float version, + QObject *parent) : + QQmlDebugService(dd, name, version, parent) { init(); } + +QMutex *QQmlConfigurableDebugService::configMutex() +{ + Q_D(QQmlConfigurableDebugService); + return &d->configMutex; +} + +void QQmlConfigurableDebugService::init() +{ + Q_D(QQmlConfigurableDebugService); + QMutexLocker lock(&d->configMutex); + // If we're not enabled or not blocking, don't wait for configuration + d->waitingForConfiguration = (registerService() == Enabled && blockingMode()); +} + +void QQmlConfigurableDebugService::stopWaiting() +{ + Q_D(QQmlConfigurableDebugService); + QMutexLocker lock(&d->configMutex); + d->waitingForConfiguration = false; + foreach (QQmlEngine *engine, d->waitingEngines) + emit attachedToEngine(engine); + d->waitingEngines.clear(); +} + +void QQmlConfigurableDebugService::stateChanged(QQmlDebugService::State newState) +{ + if (newState != Enabled) + stopWaiting(); +} + +void QQmlConfigurableDebugService::engineAboutToBeAdded(QQmlEngine *engine) +{ + Q_D(QQmlConfigurableDebugService); + QMutexLocker lock(&d->configMutex); + if (d->waitingForConfiguration) + d->waitingEngines.append(engine); + else + emit attachedToEngine(engine); +} + +QT_END_NAMESPACE diff --git a/src/qml/debugger/qqmlconfigurabledebugservice_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p.h new file mode 100644 index 0000000000..92d18bea90 --- /dev/null +++ b/src/qml/debugger/qqmlconfigurabledebugservice_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QQMLCONFIGURABLEDEBUGSEVICE_H +#define QQMLCONFIGURABLEDEBUGSEVICE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qqmldebugservice_p.h" + +QT_BEGIN_NAMESPACE + +class QMutex; +class QQmlConfigurableDebugServicePrivate; +class QQmlConfigurableDebugService : public QQmlDebugService +{ + Q_OBJECT +public: + QQmlConfigurableDebugService(const QString &name, float version, QObject *parent = 0); + +protected: + QQmlConfigurableDebugService(QQmlDebugServicePrivate &dd, const QString &name, float version, QObject *parent = 0); + + QMutex *configMutex(); + void stopWaiting(); + void init(); + + void stateChanged(State); + void engineAboutToBeAdded(QQmlEngine *); + + virtual ~QQmlConfigurableDebugService() {} +private: + Q_DISABLE_COPY(QQmlConfigurableDebugService) + Q_DECLARE_PRIVATE(QQmlConfigurableDebugService) +}; + +QT_END_NAMESPACE + +#endif // QQMLCONFIGURABLEDEBUGSEVICE_H diff --git a/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h new file mode 100644 index 0000000000..0537933889 --- /dev/null +++ b/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLCONFIGURABLEDEBUGSERVICE_P_H +#define QQMLCONFIGURABLEDEBUGSERVICE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qqmldebugservice_p.h" +#include "qqmldebugservice_p_p.h" + +#include + +QT_BEGIN_NAMESPACE + +class QQmlEngine; + +class QQmlConfigurableDebugServicePrivate : public QQmlDebugServicePrivate +{ + Q_DECLARE_PUBLIC(QQmlConfigurableDebugService) +public: + QQmlConfigurableDebugServicePrivate() : configMutex(QMutex::Recursive) {} + + QMutex configMutex; + QList waitingEngines; + bool waitingForConfiguration; +}; + +QT_END_NAMESPACE + +#endif // QQMLCONFIGURABLEDEBUGSERVICE_P_H diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp index f1e17df12b..a2bf19dee7 100644 --- a/src/qml/debugger/qqmldebugserver.cpp +++ b/src/qml/debugger/qqmldebugserver.cpp @@ -120,6 +120,22 @@ public: bool gotHello; bool blockingMode; + class EngineCondition { + public: + EngineCondition() : numServices(0), condition(new QWaitCondition) {} + + bool waitForServices(QReadWriteLock *locked, int numEngines); + + void wake(); + private: + int numServices; + + // shared pointer to allow for QHash-inflicted copying. + QSharedPointer condition; + }; + + QHash engineConditions; + QMutex helloMutex; QWaitCondition helloCondition; QQmlDebugServerThread *thread; @@ -573,12 +589,12 @@ QStringList QQmlDebugServer::serviceNames() const void QQmlDebugServer::addEngine(QQmlEngine *engine) { Q_D(QQmlDebugServer); - QReadLocker lock(&d->pluginsLock); + QWriteLocker lock(&d->pluginsLock); foreach (QQmlDebugService *service, d->plugins) service->engineAboutToBeAdded(engine); - // TODO: Later wait here for initialization. + d->engineConditions[engine].waitForServices(&d->pluginsLock, d->plugins.count()); foreach (QQmlDebugService *service, d->plugins) service->engineAdded(engine); @@ -587,12 +603,12 @@ void QQmlDebugServer::addEngine(QQmlEngine *engine) void QQmlDebugServer::removeEngine(QQmlEngine *engine) { Q_D(QQmlDebugServer); - QReadLocker lock(&d->pluginsLock); + QWriteLocker lock(&d->pluginsLock); foreach (QQmlDebugService *service, d->plugins) service->engineAboutToBeRemoved(engine); - // TODO: Later wait here for cleanup + d->engineConditions[engine].waitForServices(&d->pluginsLock, d->plugins.count()); foreach (QQmlDebugService *service, d->plugins) service->engineRemoved(engine); @@ -605,6 +621,12 @@ bool QQmlDebugServer::addService(QQmlDebugService *service) // to be executed outside of debugger thread Q_ASSERT(QThread::currentThread() != thread()); + connect(service, SIGNAL(attachedToEngine(QQmlEngine*)), + this, SLOT(wakeEngine(QQmlEngine*)), Qt::QueuedConnection); + connect(service, SIGNAL(detachedFromEngine(QQmlEngine*)), + this, SLOT(wakeEngine(QQmlEngine*)), Qt::QueuedConnection); + + QWriteLocker lock(&d->pluginsLock); if (!service || d->plugins.contains(service->name())) return false; @@ -656,6 +678,33 @@ void QQmlDebugServer::sendMessages(QQmlDebugService *service, Q_ARG(QList, prefixedMessages)); } +void QQmlDebugServer::wakeEngine(QQmlEngine *engine) +{ + // to be executed in debugger thread + Q_ASSERT(QThread::currentThread() == thread()); + + Q_D(QQmlDebugServer); + QWriteLocker lock(&d->pluginsLock); + d->engineConditions[engine].wake(); +} + +bool QQmlDebugServerPrivate::EngineCondition::waitForServices(QReadWriteLock *locked, int num) +{ + // to be executed outside of debugger thread + Q_ASSERT(QThread::currentThread() != QQmlDebugServer::instance()->thread()); + + Q_ASSERT_X(numServices == 0, Q_FUNC_INFO, "Request to wait again before previous wait finished"); + numServices = num; + return condition->wait(locked); +} + +void QQmlDebugServerPrivate::EngineCondition::wake() +{ + if (--numServices == 0) + condition->wakeAll(); + Q_ASSERT_X(numServices >=0, Q_FUNC_INFO, "Woken more often than #services."); +} + QT_END_NAMESPACE #include "moc_qqmldebugserver_p.cpp" diff --git a/src/qml/debugger/qqmldebugserver_p.h b/src/qml/debugger/qqmldebugserver_p.h index 2d3ffb9351..0675faaef7 100644 --- a/src/qml/debugger/qqmldebugserver_p.h +++ b/src/qml/debugger/qqmldebugserver_p.h @@ -87,6 +87,9 @@ public: void sendMessages(QQmlDebugService *service, const QList &messages); +private slots: + void wakeEngine(QQmlEngine *engine); + private: friend class QQmlDebugService; friend class QQmlDebugServicePrivate; diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp index f9e6643305..da62393d97 100644 --- a/src/qml/debugger/qqmldebugservice.cpp +++ b/src/qml/debugger/qqmldebugservice.cpp @@ -318,12 +318,14 @@ void QQmlDebugService::messageReceived(const QByteArray &) { } -void QQmlDebugService::engineAboutToBeAdded(QQmlEngine *) +void QQmlDebugService::engineAboutToBeAdded(QQmlEngine *engine) { + emit attachedToEngine(engine); } -void QQmlDebugService::engineAboutToBeRemoved(QQmlEngine *) +void QQmlDebugService::engineAboutToBeRemoved(QQmlEngine *engine) { + emit detachedFromEngine(engine); } void QQmlDebugService::engineAdded(QQmlEngine *) diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h index fd2a8c361a..5208b2dfa8 100644 --- a/src/qml/debugger/qqmldebugservice_p.h +++ b/src/qml/debugger/qqmldebugservice_p.h @@ -109,6 +109,10 @@ protected: virtual void engineAdded(QQmlEngine *); virtual void engineRemoved(QQmlEngine *); +signals: + void attachedToEngine(QQmlEngine *); + void detachedFromEngine(QQmlEngine *); + private: friend class QQmlDebugServer; friend class QQmlDebugServerPrivate; diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp index 0530b93a82..2c6c1e22f5 100644 --- a/src/qml/debugger/qqmlenginedebugservice.cpp +++ b/src/qml/debugger/qqmlenginedebugservice.cpp @@ -765,6 +765,7 @@ void QQmlEngineDebugService::engineAboutToBeAdded(QQmlEngine *engine) Q_ASSERT(!m_engines.contains(engine)); m_engines.append(engine); + emit attachedToEngine(engine); } void QQmlEngineDebugService::engineAboutToBeRemoved(QQmlEngine *engine) @@ -773,6 +774,7 @@ void QQmlEngineDebugService::engineAboutToBeRemoved(QQmlEngine *engine) Q_ASSERT(m_engines.contains(engine)); m_engines.removeAll(engine); + emit detachedFromEngine(engine); } void QQmlEngineDebugService::objectCreated(QQmlEngine *engine, QObject *object) diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp index 5d4574231e..a9ef5ff6b1 100644 --- a/src/qml/debugger/qqmlprofilerservice.cpp +++ b/src/qml/debugger/qqmlprofilerservice.cpp @@ -137,18 +137,15 @@ void QQmlProfilerService::animationTimerCallback(qint64 delta) } QQmlProfilerService::QQmlProfilerService() - : QQmlDebugService(QStringLiteral("CanvasFrameRate"), 1) + : QQmlConfigurableDebugService(QStringLiteral("CanvasFrameRate"), 1) { m_timer.start(); - // don't execute stateAboutToBeChanged(), messageReceived() in parallel - QMutexLocker lock(&m_initializeMutex); - - if (registerService() == Enabled) { + QMutexLocker lock(configMutex()); + // TODO: This is problematic as the service could be enabled at a later point in time. In that + // case we might miss the callback registration. + if (state() == Enabled) QUnifiedTimer::instance()->registerProfilerCallback(&animationTimerCallback); - if (blockingMode()) - m_initializeCondition.wait(&m_initializeMutex); - } } QQmlProfilerService::~QQmlProfilerService() @@ -228,27 +225,20 @@ void QQmlProfilerService::sendMessages() void QQmlProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState) { - QMutexLocker lock(&m_initializeMutex); + QMutexLocker lock(configMutex()); if (state() == newState) return; - if (state() == Enabled - && enabled) { + if (newState != Enabled && enabled) { stopProfilingImpl(); sendMessages(); } - - if (state() != Enabled) { - // wake up constructor in blocking mode - // (we might got disabled before first message arrived) - m_initializeCondition.wakeAll(); - } } void QQmlProfilerService::messageReceived(const QByteArray &message) { - QMutexLocker lock(&m_initializeMutex); + QMutexLocker lock(configMutex()); QByteArray rwData = message; QQmlDebugStream stream(&rwData, QIODevice::ReadOnly); @@ -263,8 +253,7 @@ void QQmlProfilerService::messageReceived(const QByteArray &message) sendMessages(); } - // wake up constructor in blocking mode - m_initializeCondition.wakeAll(); + stopWaiting(); } /*! diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h index cdc49f2ea7..b688141730 100644 --- a/src/qml/debugger/qqmlprofilerservice_p.h +++ b/src/qml/debugger/qqmlprofilerservice_p.h @@ -53,7 +53,7 @@ // We mean it. // -#include +#include "qqmlconfigurabledebugservice_p.h" #include // this contains QUnifiedTimer #include @@ -163,7 +163,7 @@ class QUrl; class QQmlEngine; -class Q_QML_PRIVATE_EXPORT QQmlProfilerService : public QQmlDebugService +class Q_QML_PRIVATE_EXPORT QQmlProfilerService : public QQmlConfigurableDebugService { public: enum Message { @@ -372,8 +372,6 @@ private: QElapsedTimer m_timer; QVector m_data; QMutex m_dataMutex; - QMutex m_initializeMutex; - QWaitCondition m_initializeCondition; static QQmlProfilerService *m_instance; diff --git a/src/qml/debugger/qv4debugservice.cpp b/src/qml/debugger/qv4debugservice.cpp index 0058e78e7f..8e81d6e24e 100644 --- a/src/qml/debugger/qv4debugservice.cpp +++ b/src/qml/debugger/qv4debugservice.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include "qv4debugservice_p.h" -#include "qqmldebugservice_p_p.h" +#include "qqmlconfigurabledebugservice_p_p.h" #include "qqmlengine.h" #include "qv4debugging_p.h" #include "qv4engine_p.h" @@ -358,7 +358,7 @@ private: QHash objectRefs; }; -class QV4DebugServicePrivate : public QQmlDebugServicePrivate +class QV4DebugServicePrivate : public QQmlConfigurableDebugServicePrivate { Q_DECLARE_PUBLIC(QV4DebugService) @@ -393,8 +393,6 @@ public: void processCommand(const QByteArray &command, const QByteArray &data); - QMutex initializeMutex; - QWaitCondition initializeCondition; QV4DebuggerAgent debuggerAgent; QStringList breakOnSignals; @@ -999,19 +997,9 @@ V8CommandHandler *QV4DebugServicePrivate::v8CommandHandler(const QString &comman } QV4DebugService::QV4DebugService(QObject *parent) - : QQmlDebugService(*(new QV4DebugServicePrivate()), + : QQmlConfigurableDebugService(*(new QV4DebugServicePrivate()), QStringLiteral("V8Debugger"), 1, parent) -{ - Q_D(QV4DebugService); - - // don't execute stateChanged, messageReceived in parallel - QMutexLocker lock(&d->initializeMutex); - - if (registerService() == Enabled && blockingMode()) { - // let's wait for first message ... - d->initializeCondition.wait(&d->initializeMutex); - } -} +{} QV4DebugService::~QV4DebugService() { @@ -1025,7 +1013,7 @@ QV4DebugService *QV4DebugService::instance() void QV4DebugService::engineAboutToBeAdded(QQmlEngine *engine) { Q_D(QV4DebugService); - QMutexLocker lock(&d->initializeMutex); + QMutexLocker lock(configMutex()); if (engine) { QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle()); if (QQmlDebugServer *server = QQmlDebugServer::instance()) { @@ -1039,12 +1027,13 @@ void QV4DebugService::engineAboutToBeAdded(QQmlEngine *engine) } } } + QQmlConfigurableDebugService::engineAboutToBeAdded(engine); } void QV4DebugService::engineAboutToBeRemoved(QQmlEngine *engine) { Q_D(QV4DebugService); - QMutexLocker lock(&d->initializeMutex); + QMutexLocker lock(configMutex()); if (engine){ const QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle()); if (ee) { @@ -1060,6 +1049,7 @@ void QV4DebugService::engineAboutToBeRemoved(QQmlEngine *engine) d->debuggerAgent.removeDebugger(debugger); } } + QQmlConfigurableDebugService::engineAboutToBeRemoved(engine); } void QV4DebugService::signalEmitted(const QString &signal) @@ -1081,22 +1071,10 @@ void QV4DebugService::signalEmitted(const QString &signal) } } -void QV4DebugService::stateChanged(QQmlDebugService::State newState) -{ - Q_D(QV4DebugService); - QMutexLocker lock(&d->initializeMutex); - - if (newState != Enabled) { - // wake up constructor in blocking mode - // (we might got disabled before first message arrived) - d->initializeCondition.wakeAll(); - } -} - void QV4DebugService::messageReceived(const QByteArray &message) { Q_D(QV4DebugService); - QMutexLocker lock(&d->initializeMutex); + QMutexLocker lock(configMutex()); QQmlDebugStream ms(message); QByteArray header; @@ -1112,7 +1090,7 @@ void QV4DebugService::messageReceived(const QByteArray &message) if (type == V4_CONNECT) { sendMessage(d->packMessage(type)); - d->initializeCondition.wakeAll(); + stopWaiting(); } else if (type == V4_PAUSE) { d->debuggerAgent.pauseAll(); sendSomethingToSomebody(type); diff --git a/src/qml/debugger/qv4debugservice_p.h b/src/qml/debugger/qv4debugservice_p.h index 0aa38150c6..d63d5fae1c 100644 --- a/src/qml/debugger/qv4debugservice_p.h +++ b/src/qml/debugger/qv4debugservice_p.h @@ -53,7 +53,7 @@ // We mean it. // -#include "qqmldebugservice_p.h" +#include "qqmlconfigurabledebugservice_p.h" QT_BEGIN_NAMESPACE @@ -61,7 +61,7 @@ namespace QV4 { struct ExecutionEngine; } class QQmlEngine; class QV4DebugServicePrivate; -class QV4DebugService : public QQmlDebugService +class QV4DebugService : public QQmlConfigurableDebugService { Q_OBJECT public: @@ -75,7 +75,6 @@ public: void signalEmitted(const QString &signal); protected: - void stateChanged(State newState); void messageReceived(const QByteArray &); void sendSomethingToSomebody(const char *type, int magicNumber = 1); diff --git a/src/qml/debugger/qv4profilerservice.cpp b/src/qml/debugger/qv4profilerservice.cpp index b064f57089..d8f69aecd9 100644 --- a/src/qml/debugger/qv4profilerservice.cpp +++ b/src/qml/debugger/qv4profilerservice.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include "qv4profilerservice_p.h" -#include "qqmldebugservice_p_p.h" +#include "qqmlconfigurabledebugservice_p_p.h" #include #include @@ -81,7 +81,7 @@ QByteArray QV4ProfilerData::toByteArray() const return data; } -class QV4ProfilerServicePrivate : public QQmlDebugServicePrivate +class QV4ProfilerServicePrivate : public QQmlConfigurableDebugServicePrivate { Q_DECLARE_PUBLIC(QV4ProfilerService) @@ -99,23 +99,12 @@ public: QList m_data; bool initialized; - QMutex initializeMutex; - QWaitCondition initializeCondition; QList m_ongoing; }; QV4ProfilerService::QV4ProfilerService(QObject *parent) - : QQmlDebugService(*(new QV4ProfilerServicePrivate()), QStringLiteral("V8Profiler"), 1, parent) + : QQmlConfigurableDebugService(*(new QV4ProfilerServicePrivate()), QStringLiteral("V8Profiler"), 1, parent) { - Q_D(QV4ProfilerService); - - QMutexLocker lock(&d->initializeMutex); - - if (registerService() == Enabled - && QQmlDebugService::blockingMode()) { - // let's wait for first message ... - d->initializeCondition.wait(&d->initializeMutex); - } } QV4ProfilerService::~QV4ProfilerService() @@ -130,6 +119,7 @@ QV4ProfilerService *QV4ProfilerService::instance() void QV4ProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState) { Q_D(QV4ProfilerService); + QMutexLocker lock(configMutex()); if (state() == newState) return; @@ -140,10 +130,6 @@ void QV4ProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState) Q_ARG(QString, title)); } QMetaObject::invokeMethod(this, "sendProfilingData", Qt::BlockingQueuedConnection); - } else { - // wake up constructor in blocking mode - // (we might got disabled before first message arrived) - d->initializeCondition.wakeAll(); } } @@ -157,7 +143,7 @@ void QV4ProfilerService::messageReceived(const QByteArray &message) QByteArray title; ds >> command >> option; - QMutexLocker lock(&d->initializeMutex); + QMutexLocker lock(configMutex()); if (command == "V8PROFILER") { ds >> title; @@ -180,7 +166,7 @@ void QV4ProfilerService::messageReceived(const QByteArray &message) } // wake up constructor in blocking mode - d->initializeCondition.wakeAll(); + stopWaiting(); QQmlDebugService::messageReceived(message); } diff --git a/src/qml/debugger/qv4profilerservice_p.h b/src/qml/debugger/qv4profilerservice_p.h index cf330e5a1b..b1a58dae03 100644 --- a/src/qml/debugger/qv4profilerservice_p.h +++ b/src/qml/debugger/qv4profilerservice_p.h @@ -53,7 +53,7 @@ // We mean it. // -#include +#include QT_BEGIN_NAMESPACE @@ -74,7 +74,7 @@ struct Q_AUTOTEST_EXPORT QV4ProfilerData class QQmlEngine; class QV4ProfilerServicePrivate; -class Q_AUTOTEST_EXPORT QV4ProfilerService : public QQmlDebugService +class Q_AUTOTEST_EXPORT QV4ProfilerService : public QQmlConfigurableDebugService { Q_OBJECT public: -- cgit v1.2.3