diff options
author | Ulf Hermann <ulf.hermann@digia.com> | 2014-02-26 18:42:48 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-27 22:21:52 +0100 |
commit | 553530fb0a202ba7adaa2521fc180068f98c9c20 (patch) | |
tree | 6b19ac9d646a9f3e399637a1aa164352d1b6b9f3 /src/qml/debugger/qqmlprofilerservice.cpp | |
parent | 0e770a79a70e1830c1508136020e67a3290ff1a1 (diff) |
Fix behavior when starting/stopping multiple QML profilers at once
Make sure they're all inserted into the m_startTimes map before any of
them is actually stopped. Otherwise multiple "Complete" messages can be
generated for only one profiling session.
For consistency, also allow all profilers to be started at the same
time with only one call to startProfiling().
Task-number: QTCREATORBUG-11532
Change-Id: I8f80e2f7432c31d5911e139f9632c36f2494cb96
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
Diffstat (limited to 'src/qml/debugger/qqmlprofilerservice.cpp')
-rw-r--r-- | src/qml/debugger/qqmlprofilerservice.cpp | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp index fa34fb7898..397576a99d 100644 --- a/src/qml/debugger/qqmlprofilerservice.cpp +++ b/src/qml/debugger/qqmlprofilerservice.cpp @@ -208,17 +208,45 @@ void QQmlProfilerService::removeProfilerFromStartTimes(const QQmlAbstractProfile } } +/*! + * Start profiling the given \a engine. If \a engine is 0, start all engine profilers that aren't + * currently running. + * + * If any engine profiler is started like that also start all global profilers. + */ void QQmlProfilerService::startProfiling(QQmlEngine *engine) { QMutexLocker lock(configMutex()); QByteArray message; QQmlDebugStream d(&message, QIODevice::WriteOnly); - d << m_timer.nsecsElapsed() << (int)Event << (int)StartTrace << idForObject(engine); - foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) { - profiler->startProfiling(); + + d << m_timer.nsecsElapsed() << (int)Event << (int)StartTrace; + bool startedAny = false; + if (engine != 0) { + foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) { + if (!profiler->isRunning()) { + profiler->startProfiling(); + startedAny = true; + } + } + if (startedAny) + d << idForObject(engine); + } else { + QSet<QQmlEngine *> engines; + for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); + i != m_engineProfilers.end(); ++i) { + if (!i.value()->isRunning()) { + engines << i.key(); + i.value()->startProfiling(); + startedAny = true; + } + } + foreach (QQmlEngine *profiledEngine, engines) + d << idForObject(profiledEngine); } - if (!m_engineProfilers.values(engine).empty()) { + + if (startedAny) { foreach (QQmlAbstractProfilerAdapter *profiler, m_globalProfilers) { if (!profiler->isRunning()) profiler->startProfiling(); @@ -228,32 +256,48 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine) QQmlDebugService::sendMessage(message); } +/*! + * Stop profiling the given \a engine. If \a engine is 0, stop all currently running engine + * profilers. + * + * If afterwards no more engine profilers are running, also stop all global profilers. Otherwise + * only make them report their data. + */ void QQmlProfilerService::stopProfiling(QQmlEngine *engine) { QMutexLocker lock(configMutex()); + QList<QQmlAbstractProfilerAdapter *> stopping; + QList<QQmlAbstractProfilerAdapter *> reporting; bool stillRunning = false; for (QMultiHash<QQmlEngine *, QQmlAbstractProfilerAdapter *>::iterator i(m_engineProfilers.begin()); i != m_engineProfilers.end(); ++i) { if (i.value()->isRunning()) { - if (i.key() == engine) { + if (engine == 0 || i.key() == engine) { m_startTimes.insert(-1, i.value()); - i.value()->stopProfiling(); + stopping << i.value(); } else { stillRunning = true; } } } + foreach (QQmlAbstractProfilerAdapter *profiler, m_globalProfilers) { if (!profiler->isRunning()) continue; m_startTimes.insert(-1, profiler); if (stillRunning) { - profiler->reportData(); + reporting << profiler; } else { - profiler->stopProfiling(); + stopping << profiler; } } + + foreach (QQmlAbstractProfilerAdapter *profiler, reporting) + profiler->reportData(); + + foreach (QQmlAbstractProfilerAdapter *profiler, stopping) + profiler->stopProfiling(); } /* @@ -328,22 +372,11 @@ void QQmlProfilerService::messageReceived(const QByteArray &message) if (!stream.atEnd()) stream >> engineId; - // The second time around there will be specific engineIds. - // We only have to wait after the first, empty start message. - if (engineId == -1) { - // Wait until no engine registers within RegisterTimeout anymore. - foreach (QQmlEngine *engine, m_engineProfilers.keys().toSet()) { - if (enabled) - startProfiling(engine); - else - stopProfiling(engine); - } - } else { - if (enabled) - startProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId))); - else - stopProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId))); - } + // If engineId == -1 objectForId() and then the cast will return 0. + if (enabled) + startProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId))); + else + stopProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId))); stopWaiting(); } |