Handle belowNormalPriority inside process launcher on Windows

Remove setCreateProcessArgumentModifier() from the ProcessInterface
API and replace it with belowNormalPriority flag.

Change-Id: I6bcb92e56c3a68af7fa3e3a1c8b8eb13e3a2e5a7
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2021-08-09 12:17:13 +02:00
parent d5eea3f994
commit 8fa1a1f587
8 changed files with 43 additions and 14 deletions

View File

@@ -59,13 +59,13 @@ StartProcessPacket::StartProcessPacket(quintptr token)
void StartProcessPacket::doSerialize(QDataStream &stream) const void StartProcessPacket::doSerialize(QDataStream &stream) const
{ {
stream << command << arguments << workingDir << env << processMode << writeData << channelMode stream << command << arguments << workingDir << env << processMode << writeData << channelMode
<< standardInputFile; << standardInputFile << belowNormalPriority;
} }
void StartProcessPacket::doDeserialize(QDataStream &stream) void StartProcessPacket::doDeserialize(QDataStream &stream)
{ {
stream >> command >> arguments >> workingDir >> env >> processMode >> writeData >> channelMode stream >> command >> arguments >> workingDir >> env >> processMode >> writeData >> channelMode
>> standardInputFile; >> standardInputFile >> belowNormalPriority;
} }

View File

@@ -115,6 +115,7 @@ public:
QByteArray writeData; QByteArray writeData;
QProcess::ProcessChannelMode channelMode = QProcess::SeparateChannels; QProcess::ProcessChannelMode channelMode = QProcess::SeparateChannels;
QString standardInputFile; QString standardInputFile;
bool belowNormalPriority = false;
private: private:
void doSerialize(QDataStream &stream) const override; void doSerialize(QDataStream &stream) const override;

View File

@@ -409,6 +409,7 @@ void LauncherHandle::doStart()
p.writeData = m_writeData; p.writeData = m_writeData;
p.channelMode = m_channelMode; p.channelMode = m_channelMode;
p.standardInputFile = m_standardInputFile; p.standardInputFile = m_standardInputFile;
p.belowNormalPriority = m_belowNormalPriority;
sendPacket(p); sendPacket(p);
} }

View File

@@ -102,6 +102,9 @@ public:
{ QMutexLocker locker(&m_mutex); m_environment = environment; } { QMutexLocker locker(&m_mutex); m_environment = environment; }
void setWorkingDirectory(const QString &dir) { QMutexLocker locker(&m_mutex); m_workingDirectory = dir; } void setWorkingDirectory(const QString &dir) { QMutexLocker locker(&m_mutex); m_workingDirectory = dir; }
QProcess::ExitStatus exitStatus() const { QMutexLocker locker(&m_mutex); return m_exitStatus; } QProcess::ExitStatus exitStatus() const { QMutexLocker locker(&m_mutex); return m_exitStatus; }
void setBelowNormalPriority() { m_belowNormalPriority = true; }
signals: signals:
void errorOccurred(QProcess::ProcessError error); void errorOccurred(QProcess::ProcessError error);
void started(); void started();
@@ -181,6 +184,8 @@ private:
CallerHandle *m_callerHandle = nullptr; CallerHandle *m_callerHandle = nullptr;
bool m_belowNormalPriority = false;
friend class LauncherSocket; friend class LauncherSocket;
friend class CallerHandle; friend class CallerHandle;
}; };

View File

@@ -26,6 +26,13 @@
#include "processutils.h" #include "processutils.h"
#include <QProcess> #include <QProcess>
#ifdef Q_OS_WIN
#ifdef QTCREATOR_PCH_H
#define CALLBACK WINAPI
#endif
#include <qt_windows.h>
#endif
namespace Utils { namespace Utils {
QIODevice::OpenMode ProcessStartHandler::openMode() const QIODevice::OpenMode ProcessStartHandler::openMode() const
@@ -55,4 +62,16 @@ void ProcessStartHandler::handleProcessStarted(QProcess *process)
} }
} }
void ProcessStartHandler::setBelowNormalPriority(QProcess *process)
{
#ifdef Q_OS_WIN
process->setCreateProcessArgumentsModifier(
[](QProcess::CreateProcessArguments *args) {
args->flags |= BELOW_NORMAL_PRIORITY_CLASS;
});
#endif // Q_OS_WIN
}
} // namespace Utils } // namespace Utils

View File

@@ -46,6 +46,7 @@ public:
QIODevice::OpenMode openMode() const; QIODevice::OpenMode openMode() const;
void handleProcessStart(QProcess *process); void handleProcessStart(QProcess *process);
void handleProcessStarted(QProcess *process); void handleProcessStarted(QProcess *process);
void setBelowNormalPriority(QProcess *process);
private: private:
ProcessMode m_processMode = ProcessMode::Reader; ProcessMode m_processMode = ProcessMode::Reader;

View File

@@ -136,8 +136,10 @@ public:
virtual bool lowPriority() const = 0; virtual bool lowPriority() const = 0;
virtual void setDisableUnixTerminal() = 0; virtual void setDisableUnixTerminal() = 0;
void setBelowNormalPriority() { m_belowNormalPriority = true; }
bool isBelowNormalPriority() const { return m_belowNormalPriority; }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
virtual void setCreateProcessArgumentsModifier(QProcess::CreateProcessArgumentModifier modifier) = 0;
virtual void setNativeArguments(const QString &arguments) = 0; virtual void setNativeArguments(const QString &arguments) = 0;
#endif #endif
@@ -152,6 +154,7 @@ protected:
ProcessMode processMode() const { return m_processMode; } ProcessMode processMode() const { return m_processMode; }
private: private:
const ProcessMode m_processMode; const ProcessMode m_processMode;
bool m_belowNormalPriority = false;
}; };
class ProcessHelper : public QProcess class ProcessHelper : public QProcess
@@ -218,6 +221,8 @@ public:
{ {
m_processStartHandler.setProcessMode(processMode()); m_processStartHandler.setProcessMode(processMode());
m_processStartHandler.setWriteData(writeData); m_processStartHandler.setWriteData(writeData);
if (isBelowNormalPriority())
m_processStartHandler.setBelowNormalPriority(&m_process);
m_process.start(program, arguments, m_processStartHandler.openMode()); m_process.start(program, arguments, m_processStartHandler.openMode());
m_processStartHandler.handleProcessStart(&m_process); m_processStartHandler.handleProcessStart(&m_process);
} }
@@ -265,8 +270,6 @@ public:
{ m_process.m_disableUnixTerminal = true; } { m_process.m_disableUnixTerminal = true; }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
void setCreateProcessArgumentsModifier(QProcess::CreateProcessArgumentModifier modifier) override
{ m_process.setCreateProcessArgumentsModifier(modifier); }
void setNativeArguments(const QString &arguments) override void setNativeArguments(const QString &arguments) override
{ m_process.setNativeArguments(arguments); } { m_process.setNativeArguments(arguments); }
#endif #endif
@@ -319,7 +322,11 @@ public:
{ m_handle->setProcessEnvironment(environment); } { m_handle->setProcessEnvironment(environment); }
void setWorkingDirectory(const QString &dir) override { m_handle->setWorkingDirectory(dir); } void setWorkingDirectory(const QString &dir) override { m_handle->setWorkingDirectory(dir); }
void start(const QString &program, const QStringList &arguments, const QByteArray &writeData) override void start(const QString &program, const QStringList &arguments, const QByteArray &writeData) override
{ m_handle->start(program, arguments, writeData); } {
if (isBelowNormalPriority())
m_handle->setBelowNormalPriority();
m_handle->start(program, arguments, writeData);
}
void terminate() override { cancel(); } // TODO: what are differences among terminate, kill and close? void terminate() override { cancel(); } // TODO: what are differences among terminate, kill and close?
void kill() override { cancel(); } // TODO: see above void kill() override { cancel(); } // TODO: see above
void close() override { cancel(); } // TODO: see above void close() override { cancel(); } // TODO: see above
@@ -345,8 +352,6 @@ public:
void setDisableUnixTerminal() override { QTC_CHECK(false); } void setDisableUnixTerminal() override { QTC_CHECK(false); }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
void setCreateProcessArgumentsModifier(QProcess::CreateProcessArgumentModifier modifier) override
{ QTC_CHECK(false); }
void setNativeArguments(const QString &arguments) override { QTC_CHECK(false); } void setNativeArguments(const QString &arguments) override { QTC_CHECK(false); }
#endif #endif
@@ -619,12 +624,7 @@ void QtcProcess::start()
command = QCoreApplication::applicationDirPath() command = QCoreApplication::applicationDirPath()
+ QLatin1String("/qtcreator_ctrlc_stub.exe"); + QLatin1String("/qtcreator_ctrlc_stub.exe");
} else if (d->m_process->lowPriority()) { } else if (d->m_process->lowPriority()) {
#ifdef Q_OS_WIN d->m_process->setBelowNormalPriority();
d->m_process->setCreateProcessArgumentsModifier(
[](QProcess::CreateProcessArguments *args) {
args->flags |= BELOW_NORMAL_PRIORITY_CLASS;
});
#endif
} }
ProcessArgs::addArgs(&args, arguments.toWindowsArgs()); ProcessArgs::addArgs(&args, arguments.toWindowsArgs());
#ifdef Q_OS_WIN #ifdef Q_OS_WIN

View File

@@ -243,6 +243,8 @@ void LauncherSocketHandler::handleStartPacket()
ProcessStartHandler *handler = process->processStartHandler(); ProcessStartHandler *handler = process->processStartHandler();
handler->setProcessMode(packet.processMode); handler->setProcessMode(packet.processMode);
handler->setWriteData(packet.writeData); handler->setWriteData(packet.writeData);
if (packet.belowNormalPriority)
handler->setBelowNormalPriority(process);
process->start(packet.command, packet.arguments, handler->openMode()); process->start(packet.command, packet.arguments, handler->openMode());
handler->handleProcessStart(process); handler->handleProcessStart(process);
} }