ProjectExplorer: Run RunControl::{start,stop} always asynchronously

This introduces a mini-state-"machine" to handle RunControl states
Intialized->[Starting->Running->Stopping->Stopped->]*->Finished.

Needing time between trying to start and getting feedback is nowadays
the normal setup for all remote targets as well as for most local tools.
Making that the default for all runs simplifies the code and provides an
opportunity to (a) fix some currently wrong reports of "stopped
immediately" and (b) to remove target-specific (WinRT) or tool-specific
(Valgrind, GammaRay) state members doing essentially the same.

Change-Id: I7f52fee41144188ee8389e922fdc265f8c0a6459
Reviewed-by: David Schulz <david.schulz@qt.io>
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
hjk
2017-03-13 13:48:55 +01:00
parent 1a416d3f98
commit 2360a2d743
26 changed files with 155 additions and 111 deletions

View File

@@ -118,9 +118,9 @@ void QmlProfilerRunControl::start()
emit starting();
}
RunControl::StopResult QmlProfilerRunControl::stop()
void QmlProfilerRunControl::stop()
{
QTC_ASSERT(d->m_profilerState, return RunControl::StoppedSynchronously);
QTC_ASSERT(d->m_profilerState, return);
switch (d->m_profilerState->currentState()) {
case QmlProfilerStateManager::AppRunning:
@@ -141,8 +141,6 @@ RunControl::StopResult QmlProfilerRunControl::stop()
}
break;
}
return RunControl::StoppedSynchronously;
}
void QmlProfilerRunControl::notifyRemoteFinished()

View File

@@ -48,7 +48,7 @@ public:
void notifyRemoteSetupDone(Utils::Port port) override;
void notifyRemoteSetupFailed(const QString &errorMessage) override;
void start() override;
StopResult stop() override;
void stop() override;
void cancelProcess();
void notifyRemoteFinished() override;
bool supportsReRunning() const override { return false; }

View File

@@ -37,40 +37,39 @@ LocalQmlProfilerRunnerTest::LocalQmlProfilerRunnerTest(QObject *parent) : QObjec
{
}
void LocalQmlProfilerRunnerTest::connectRunner(LocalQmlProfilerRunner *runner)
{
connect(runner, &LocalQmlProfilerRunner::started, this, [this] {
QVERIFY(!running);
++runCount;
running = true;
});
connect(runner, &LocalQmlProfilerRunner::stopped, this, [this] {
QVERIFY(running);
running = false;
});
}
void LocalQmlProfilerRunnerTest::testRunner()
{
Debugger::AnalyzerConnection connection;
LocalQmlProfilerRunner::Configuration configuration;
configuration.debuggee.executable = "\\-/|\\-/";
configuration.debuggee.environment = Utils::Environment::systemEnvironment();
// should not be used anywhere but cannot be empty
configuration.socket = connection.analyzerSocket = QString("invalid");
Debugger::AnalyzerRunControl *rc = Debugger::createAnalyzerRunControl(
rc = Debugger::createAnalyzerRunControl(
nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
rc->setConnection(connection);
auto runner = new LocalQmlProfilerRunner(configuration, rc);
connectRunner(runner);
bool running = false;
int runCount = 0;
auto connectRunner = [&]() {
connect(runner, &LocalQmlProfilerRunner::started, this, [&running, &runCount](){
QVERIFY(!running);
++runCount;
running = true;
});
connect(runner, &LocalQmlProfilerRunner::stopped, this, [&running](){
QVERIFY(running);
running = false;
});
};
connectRunner();
rc->start();
rc->initiateStart();
QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner1);
}
void LocalQmlProfilerRunnerTest::testRunner1()
{
QTRY_COMPARE_WITH_TIMEOUT(runCount, 1, 10000);
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
@@ -84,10 +83,14 @@ void LocalQmlProfilerRunnerTest::testRunner()
rc = Debugger::createAnalyzerRunControl(
nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
rc->setConnection(connection);
runner = new LocalQmlProfilerRunner(configuration, rc);
connectRunner();
rc->start();
auto runner = new LocalQmlProfilerRunner(configuration, rc);
connectRunner(runner);
rc->initiateStart();
QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner2);
}
void LocalQmlProfilerRunnerTest::testRunner2()
{
QTRY_COMPARE_WITH_TIMEOUT(runCount, 2, 10000);
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
@@ -101,17 +104,25 @@ void LocalQmlProfilerRunnerTest::testRunner()
rc = Debugger::createAnalyzerRunControl(
nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
rc->setConnection(connection);
runner = new LocalQmlProfilerRunner(configuration, rc);
connectRunner();
rc->start();
auto runner = new LocalQmlProfilerRunner(configuration, rc);
connectRunner(runner);
rc->initiateStart();
QTRY_COMPARE_WITH_TIMEOUT(runCount, 3, 10000);
rc->stop();
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
delete rc;
QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner3);
}
void LocalQmlProfilerRunnerTest::testRunner3()
{
QTRY_COMPARE_WITH_TIMEOUT(runCount, 3, 10000);
rc->initiateStop();
QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner4);
}
void LocalQmlProfilerRunnerTest::testRunner4()
{
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
delete rc;
}
void LocalQmlProfilerRunnerTest::testFindFreePort()
{

View File

@@ -27,7 +27,7 @@
#include <qmlprofiler/localqmlprofilerrunner.h>
#include <qmlprofiler/qmlprofilermodelmanager.h>
#include <QObject>
#include <debugger/analyzer/analyzerstartparameters.h>
namespace QmlProfiler {
namespace Internal {
@@ -42,6 +42,19 @@ private slots:
void testRunner();
void testFindFreePort();
void testFindFreeSocket();
private:
void connectRunner(LocalQmlProfilerRunner *runner);
void testRunner1();
void testRunner2();
void testRunner3();
void testRunner4();
bool running = false;
int runCount = 0;
Debugger::AnalyzerRunControl *rc = nullptr;
Debugger::AnalyzerConnection connection;
LocalQmlProfilerRunner::Configuration configuration;
};
} // namespace Internal