aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/debugger/qqmldebugserver.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@digia.com>2014-02-06 14:43:26 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-10 14:28:17 +0100
commit4cc230ade4df3919fbb9688b60e6e8f7f3cc8144 (patch)
treea6240d82988ec658d18be30e2ebf19bed2fc272d /src/qml/debugger/qqmldebugserver.cpp
parent77686f3b94dfd572778eb8dfa77717114e3abb93 (diff)
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 <kai.koehne@digia.com>
Diffstat (limited to 'src/qml/debugger/qqmldebugserver.cpp')
-rw-r--r--src/qml/debugger/qqmldebugserver.cpp57
1 files changed, 53 insertions, 4 deletions
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<QWaitCondition> condition;
+ };
+
+ QHash<QQmlEngine *, EngineCondition> 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<QByteArray>, 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"