QmlProfiler: Use EngineControl to hold engines until we're done

Holding the engines with EngineControl makes sure we always receive the
full trace before the connection drops.

Change-Id: I32e7d17886cdbc4749e3e54719e198d45169cbfe
Task-number: QTBUG-66269
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Ulf Hermann
2018-02-08 15:28:14 +01:00
parent 89a6611e9e
commit a2581a2a89

View File

@@ -77,6 +77,8 @@ public:
QStack<QmlTypedEvent> rangesInProgress; QStack<QmlTypedEvent> rangesInProgress;
QQueue<QmlEvent> pendingMessages; QQueue<QmlEvent> pendingMessages;
QQueue<QmlEvent> pendingDebugMessages; QQueue<QmlEvent> pendingDebugMessages;
QList<int> trackedEngines;
}; };
int QmlProfilerTraceClientPrivate::resolveType(const QmlTypedEvent &event) int QmlProfilerTraceClientPrivate::resolveType(const QmlTypedEvent &event)
@@ -216,6 +218,22 @@ QmlProfilerTraceClient::QmlProfilerTraceClient(QmlDebug::QmlDebugConnection *cli
setRequestedFeatures(features); setRequestedFeatures(features);
connect(&d->engineControl, &QmlDebug::QmlEngineControlClient::engineAboutToBeAdded, connect(&d->engineControl, &QmlDebug::QmlEngineControlClient::engineAboutToBeAdded,
this, &QmlProfilerTraceClient::sendRecordingStatus); this, &QmlProfilerTraceClient::sendRecordingStatus);
connect(&d->engineControl, &QmlDebug::QmlEngineControlClient::engineAboutToBeRemoved,
this, [this](int engineId) {
// We may already be done with that engine. Then we don't need to block it.
if (d->trackedEngines.contains(engineId))
d->engineControl.blockEngine(engineId);
});
connect(this, &QmlProfilerTraceClient::traceFinished,
&d->engineControl, [this](qint64 timestamp, const QList<int> &engineIds) {
Q_UNUSED(timestamp);
// The engines might not be blocked because the trace can get finished before engine control
// sees them.
for (int blocked : d->engineControl.blockedEngines()) {
if (engineIds.contains(blocked))
d->engineControl.releaseEngine(blocked);
}
});
} }
QmlProfilerTraceClient::~QmlProfilerTraceClient() QmlProfilerTraceClient::~QmlProfilerTraceClient()
@@ -243,6 +261,7 @@ void QmlProfilerTraceClient::clear()
{ {
d->eventTypeIds.clear(); d->eventTypeIds.clear();
d->serverTypeIds.clear(); d->serverTypeIds.clear();
d->trackedEngines.clear();
clearEvents(); clearEvents();
} }
@@ -334,12 +353,15 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
emit complete(d->maximumTime); emit complete(d->maximumTime);
} else if (d->currentEvent.type.message() == Event } else if (d->currentEvent.type.message() == Event
&& d->currentEvent.type.detailType() == StartTrace) { && d->currentEvent.type.detailType() == StartTrace) {
emit traceStarted(d->currentEvent.event.timestamp(), const QList<int> engineIds = d->currentEvent.event.numbers<QList<int>, qint32>();
d->currentEvent.event.numbers<QList<int>, qint32>()); d->trackedEngines.append(engineIds);
emit traceStarted(d->currentEvent.event.timestamp(), engineIds);
} else if (d->currentEvent.type.message() == Event } else if (d->currentEvent.type.message() == Event
&& d->currentEvent.type.detailType() == EndTrace) { && d->currentEvent.type.detailType() == EndTrace) {
emit traceFinished(d->currentEvent.event.timestamp(), const QList<int> engineIds = d->currentEvent.event.numbers<QList<int>, qint32>();
d->currentEvent.event.numbers<QList<int>, qint32>()); for (int engineId : engineIds)
d->trackedEngines.removeAll(engineId);
emit traceFinished(d->currentEvent.event.timestamp(), engineIds);
} else if (d->updateFeatures(d->currentEvent.type.feature())) { } else if (d->updateFeatures(d->currentEvent.type.feature())) {
d->processCurrentEvent(); d->processCurrentEvent();
} }