forked from qt-creator/qt-creator
Process: Fix EventLoopMode::On
Queue the call to start() so that it's executed after the nested event loop is started, otherwise it fails on Windows with QProcessImpl. Fixes: QTCREATORBUG-30066 Change-Id: Ibb17ef0f668f52c05b26a521e18c94e637992ba5 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -1865,23 +1865,22 @@ void Process::setWriteData(const QByteArray &writeData)
|
||||
|
||||
void Process::runBlocking(EventLoopMode eventLoopMode)
|
||||
{
|
||||
QDateTime startTime;
|
||||
static const int blockingThresholdMs = qtcEnvironmentVariableIntValue("QTC_PROCESS_THRESHOLD");
|
||||
|
||||
auto starter = [this, eventLoopMode, &startTime] {
|
||||
// Attach a dynamic property with info about blocking type
|
||||
d->storeEventLoopDebugInfo(int(eventLoopMode));
|
||||
|
||||
QDateTime startTime;
|
||||
static const int blockingThresholdMs = qtcEnvironmentVariableIntValue("QTC_PROCESS_THRESHOLD");
|
||||
if (blockingThresholdMs > 0 && isMainThread())
|
||||
startTime = QDateTime::currentDateTime();
|
||||
Process::start();
|
||||
start();
|
||||
|
||||
// Remove the dynamic property so that it's not reused in subseqent start()
|
||||
d->storeEventLoopDebugInfo({});
|
||||
};
|
||||
|
||||
if (eventLoopMode == EventLoopMode::On) {
|
||||
// Start failure is triggered immediately if the executable cannot be found in the path.
|
||||
// In this case the process is left in NotRunning state.
|
||||
// Do not start the event loop in that case.
|
||||
if (state() == QProcess::Starting) {
|
||||
QTimer timer(this);
|
||||
connect(&timer, &QTimer::timeout, d, &ProcessPrivate::slotTimeout);
|
||||
timer.setInterval(1000);
|
||||
@@ -1893,6 +1892,9 @@ void Process::runBlocking(EventLoopMode eventLoopMode)
|
||||
QEventLoop eventLoop(this);
|
||||
QTC_ASSERT(!d->m_eventLoop, return);
|
||||
d->m_eventLoop = &eventLoop;
|
||||
// Queue the call to start() so that it's executed after the nested event loop is started,
|
||||
// otherwise it fails on Windows with QProcessImpl. See QTCREATORBUG-30066.
|
||||
QMetaObject::invokeMethod(this, starter, Qt::QueuedConnection);
|
||||
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
|
||||
d->m_eventLoop = nullptr;
|
||||
timer.stop();
|
||||
@@ -1900,8 +1902,8 @@ void Process::runBlocking(EventLoopMode eventLoopMode)
|
||||
if (isGuiEnabled())
|
||||
QGuiApplication::restoreOverrideCursor();
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
starter();
|
||||
if (!waitForStarted(d->m_maxHangTimerCount * 1000)) {
|
||||
d->m_result = ProcessResult::StartFailed;
|
||||
return;
|
||||
|
||||
@@ -1595,17 +1595,7 @@ void tst_Process::eventLoopMode()
|
||||
subConfig.setupSubProcess(&process);
|
||||
process.setProcessImpl(processImpl);
|
||||
process.runBlocking(eventLoopMode);
|
||||
const ProcessResult actualResult = process.result();
|
||||
|
||||
// FIXME: On Windows, Process::runBlocking(EventLoopMode::On) and ProcessImpl::QProcess fails
|
||||
// with ProcessResult::StartFailed. Details: QTCREATORBUG-30066
|
||||
const bool isFailingCombination = HostOsInfo::isWindowsHost()
|
||||
&& processImpl == ProcessImpl::QProcess
|
||||
&& eventLoopMode == EventLoopMode::On;
|
||||
const ProcessResult expectedResult = isFailingCombination ? ProcessResult::StartFailed
|
||||
: ProcessResult::FinishedWithSuccess;
|
||||
|
||||
QCOMPARE(actualResult, expectedResult);
|
||||
QCOMPARE(process.result(), ProcessResult::FinishedWithSuccess);
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(tst_Process)
|
||||
|
||||
Reference in New Issue
Block a user