Utils: fix QProcess backend on Windows

Do not return false from QtcProces::waitForStarted if the process is
already running. This causes mayor issues on windows since QProcess
directly emits started and therefore switches to the running state after
calling QProcess::start.

Change-Id: I4604b08a59918d3df11c8a174b57e1e483e78a0d
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
David Schulz
2022-04-25 07:18:00 +02:00
parent a5a06fe355
commit 11ce6e365f
4 changed files with 59 additions and 1 deletions

View File

@@ -1166,7 +1166,9 @@ qint64 QtcProcess::processId() const
bool QtcProcess::waitForStarted(int msecs)
{
QTC_ASSERT(d->m_process, return false);
if (d->m_state != QProcess::Starting)
if (d->m_state == QProcess::Running)
return true;
if (d->m_state == QProcess::NotRunning)
return false;
return s_waitForStarted.measureAndRun(&ProcessInterface::waitForStarted, d->m_process, msecs);
}

View File

@@ -106,6 +106,14 @@ void SubProcessConfig::setupSubProcess(QtcProcess *subProcess)
subProcess->setCommand(CommandLine(filePath, {}));
}
void SubProcessConfig::setupSubProcess(QProcess *subProcess)
{
subProcess->setProcessEnvironment(m_environment.toProcessEnvironment());
subProcess->setProgram(FilePath::fromString(s_pathToProcessTestApp
+ QLatin1String("/processtestapp")).withExecutableSuffix().toString());
}
static void doCrash()
{
qFatal("The application has crashed purposefully!");

View File

@@ -29,6 +29,10 @@
#include <utils/environment.h>
#include <utils/qtcassert.h>
QT_BEGIN_NAMESPACE
class QProcess;
QT_END_NAMESPACE
namespace Utils { class QtcProcess; }
#define SUB_PROCESS(SubProcessClass)\
@@ -91,6 +95,7 @@ class SubProcessConfig
public:
SubProcessConfig(const char *envVar, const QString &envVal);
void setupSubProcess(Utils::QtcProcess *subProcess);
void setupSubProcess(QProcess *subProcess);
static void setPathToProcessTestApp(const QString &path);

View File

@@ -151,6 +151,8 @@ private slots:
void runBlockingStdOut_data();
void runBlockingStdOut();
void lineCallback();
void waitForStartedAfterStarted();
void waitForStartedAfterStarted2();
void waitForStartedAndFinished();
void notRunningAfterStartingNonExistingProgram();
void channelForwarding_data();
@@ -965,6 +967,47 @@ void tst_QtcProcess::lineCallback()
QCOMPARE(lineNumber, lines.size());
}
void tst_QtcProcess::waitForStartedAfterStarted()
{
SubProcessConfig subConfig(ProcessTestApp::SimpleTest::envVar(), {});
TestProcess process;
subConfig.setupSubProcess(&process);
bool started = false;
bool waitForStartedResult = false;
connect(&process, &QtcProcess::started, this, [&] {
started = true;
waitForStartedResult = process.waitForStarted();
});
process.start();
QVERIFY(process.waitForFinished());
QVERIFY(started);
QVERIFY(waitForStartedResult);
QVERIFY(!process.waitForStarted());
}
// This version is using QProcess
void tst_QtcProcess::waitForStartedAfterStarted2()
{
SubProcessConfig subConfig(ProcessTestApp::SimpleTest::envVar(), {});
QProcess process;
subConfig.setupSubProcess(&process);
bool started = false;
bool waitForStartedResult = false;
connect(&process, &QProcess::started, this, [&] {
started = true;
waitForStartedResult = process.waitForStarted();
});
process.start();
QVERIFY(process.waitForFinished());
QVERIFY(started);
QVERIFY(waitForStartedResult);
QVERIFY(!process.waitForStarted());
}
void tst_QtcProcess::waitForStartedAndFinished()
{
SubProcessConfig subConfig(ProcessTestApp::SimpleTest::envVar(), {});