From 15c183fce614826db6e313086dccb0115a08bf66 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 30 Aug 2021 16:29:08 +0200 Subject: [PATCH] Set process state to NotRunning after FailedToStart error Remove the process in process launcher after error has appeared. Remove unneeded stopStopProcedure as we are disconnecting from process' signals inside removeProcess(). In order to behave as much similar to what QProcess does, provide a test that: - ensures the FailedToStart error is synchronously emitted when waitForStarted is being executed - ensures that process state is reset to NotRunning after FailedToStart error - 2nd call to start/waitForStarted doesn't block on waitForStarted Change-Id: I139354421d037739f1cc1a2685b66f1e5b6170c8 Reviewed-by: Christian Stenger --- src/libs/utils/launchersocket.cpp | 1 + .../processlauncher/launchersockethandler.cpp | 13 ++------ .../auto/utils/qtcprocess/tst_qtcprocess.cpp | 31 +++++++++++++++++++ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/libs/utils/launchersocket.cpp b/src/libs/utils/launchersocket.cpp index c27346f6582..1a1a4a92ef1 100644 --- a/src/libs/utils/launchersocket.cpp +++ b/src/libs/utils/launchersocket.cpp @@ -213,6 +213,7 @@ bool CallerHandle::shouldFlushFor(SignalType signalType) const void CallerHandle::handleError(const ErrorSignal *launcherSignal) { QTC_ASSERT(isCalledFromCallersThread(), return); + m_processState = QProcess::NotRunning; m_error = launcherSignal->error(); m_errorString = launcherSignal->errorString(); emit errorOccurred(m_error); diff --git a/src/tools/processlauncher/launchersockethandler.cpp b/src/tools/processlauncher/launchersockethandler.cpp index 73234347346..c83b86a0dbf 100644 --- a/src/tools/processlauncher/launchersockethandler.cpp +++ b/src/tools/processlauncher/launchersockethandler.cpp @@ -71,12 +71,6 @@ public: } } - void stopStopProcedure() - { - m_stopState = StopState::Inactive; - m_stopTimer->stop(); - } - quintptr token() const { return m_token; } ProcessStartHandler *processStartHandler() { return &m_processStartHandler; } @@ -176,13 +170,11 @@ void LauncherSocketHandler::handleSocketClosed() void LauncherSocketHandler::handleProcessError() { Process * proc = senderProcess(); - if (proc->error() != QProcess::FailedToStart) - return; - proc->stopStopProcedure(); ProcessErrorPacket packet(proc->token()); packet.error = proc->error(); packet.errorString = proc->errorString(); sendPacket(packet); + removeProcess(proc->token()); } void LauncherSocketHandler::handleProcessStarted() @@ -213,7 +205,6 @@ void LauncherSocketHandler::handleReadyReadStandardError() void LauncherSocketHandler::handleProcessFinished() { Process * proc = senderProcess(); - proc->stopStopProcedure(); ProcessFinishedPacket packet(proc->token()); packet.error = proc->error(); packet.errorString = proc->errorString(); @@ -342,7 +333,7 @@ void LauncherSocketHandler::removeProcess(quintptr token) if (process->state() != QProcess::NotRunning) process->cancel(); else - delete process; + process->deleteLater(); } Process *LauncherSocketHandler::senderProcess() const diff --git a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp index 0a23a293ca9..57230ffe5c0 100644 --- a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp +++ b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -141,6 +142,7 @@ private slots: void lineCallback(); void lineCallbackIntern(); void waitForStartedAndFinished(); + void notRunningAfterStartingNonExistingProgram(); void cleanupTestCase(); @@ -976,6 +978,35 @@ void tst_QtcProcess::waitForStartedAndFinished() QCOMPARE(process.exitCode(), 0); } +void tst_QtcProcess::notRunningAfterStartingNonExistingProgram() +{ + QtcProcess process; + process.setCommand({ FilePath::fromString( + "there_is_a_big_chance_that_executable_with_that_name_does_not_exists"), {} }); + + int errorCount = 0; + QObject::connect(&process, &QtcProcess::errorOccurred, + [&errorCount](QProcess::ProcessError error) { + ++errorCount; + QCOMPARE(error, QProcess::FailedToStart); + }); + + const int loopCount = 2; + for (int i = 0; i < loopCount; ++i) { + // Work on the same process instance on every iteration + process.start(); + + QElapsedTimer timer; + timer.start(); + const int maxWaitTimeMs = 1000; + + QVERIFY(!process.waitForStarted(maxWaitTimeMs)); + QVERIFY(timer.elapsed() < maxWaitTimeMs); // shouldn't wait, should finish immediately + QCOMPARE(process.state(), QProcess::NotRunning); + QVERIFY(process.exitCode() != 0); + } +} + QTEST_MAIN(tst_QtcProcess) #include "tst_qtcprocess.moc"