diff options
author | Ulf Hermann <ulf.hermann@digia.com> | 2014-02-06 14:43:26 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-10 14:28:17 +0100 |
commit | 4cc230ade4df3919fbb9688b60e6e8f7f3cc8144 (patch) | |
tree | a6240d82988ec658d18be30e2ebf19bed2fc272d /src/qml/debugger/qqmldebugserver.cpp | |
parent | 77686f3b94dfd572778eb8dfa77717114e3abb93 (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.cpp | 57 |
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" |