Use refactored ProcessMode

This patch needs to be applied together with the parent change.

There are 3 basic cases:
1. The user doesn't write anything to the write channel:
   You don't need to call closeWriteChannel manually anymore.
   By default the QtcProcess you create is in ProcessMode::Reader mode.
   Internally it opens the process in ReadOnly mode and
   closes the write channel just after starting.
2. The user writes some initial data (after being started)
   and then closes the write channel:
   All what is needed now it to set the write data
   (QtcProcess::setWriteData) before calling start.
   You also use the default ProcessMode::Reader mode.
   Internally it opens the process in ReadWrite mode
   and writes the writeData asynchonously when the process
   already started. After writing the data it closes the
   write channel automatically.
3. The user writes the data also after calling start.
   All you need now is to create a process with
   ProcessMode::Writer mode. In this mode the write
   channel is not closed.
   Internally it opens the process in ReadWrite mode
   as some writers also read the data from the process.

All the code base is adapted here to the above rules.

Change-Id: Id103019d1d71a3012fd1eade226fe96b9aaa48c2
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2021-08-07 11:41:23 +02:00
parent 25f585227f
commit d22505c41f
23 changed files with 20 additions and 91 deletions

View File

@@ -260,7 +260,6 @@ Archive *Archive::unarchive(const FilePath &src, const FilePath &dest)
: CommandLine{tool->executable, tool->arguments};
archive->m_process->setCommand(cmd);
archive->m_process->setWorkingDirectory(workingDirectory);
archive->m_process->setOpenMode(QProcess::ReadOnly);
archive->m_process->start();
return archive;
}

View File

@@ -116,7 +116,6 @@ public:
virtual void kill() = 0;
virtual void close() = 0;
virtual qint64 write(const QByteArray &data) = 0;
virtual void closeWriteChannel() = 0;
virtual void setStandardInputFile(const QString &fileName) = 0;
virtual void setProcessChannelMode(QProcess::ProcessChannelMode mode) = 0;
@@ -230,8 +229,6 @@ public:
{ m_process.close(); }
qint64 write(const QByteArray &data) override
{ return m_process.write(data); }
void closeWriteChannel() override
{ m_process.closeWriteChannel(); }
void setStandardInputFile(const QString &fileName) override
{ m_process.setStandardInputFile(fileName); }
@@ -327,7 +324,6 @@ public:
void kill() override { cancel(); } // TODO: see above
void close() override { cancel(); } // TODO: see above
qint64 write(const QByteArray &data) override { return m_handle->write(data); }
void closeWriteChannel() override { /*QTC_CHECK(false);*/ }
void setStandardInputFile(const QString &fileName) override { m_handle->setStandardInputFile(fileName); }
void setProcessChannelMode(QProcess::ProcessChannelMode mode) override { m_handle->setProcessChannelMode(mode); }
@@ -433,8 +429,6 @@ public:
bool m_haveEnv = false;
bool m_useCtrlCStub = false;
QProcess::OpenMode m_openMode = QProcess::ReadWrite;
void slotTimeout();
void slotFinished(int exitCode, QProcess::ExitStatus e);
void slotError(QProcess::ProcessError);
@@ -458,7 +452,6 @@ public:
bool m_timeOutMessageBoxEnabled = false;
bool m_waitingForUser = false;
bool m_processUserEvents = false;
bool m_keepStdInOpen = false;
};
void QtcProcessPrivate::clearForRun()
@@ -512,6 +505,11 @@ QtcProcess::~QtcProcess()
delete d;
}
ProcessMode QtcProcess::processMode() const
{
return d->m_processMode;
}
void QtcProcess::setEnvironment(const Environment &env)
{
d->m_environment = env;
@@ -582,14 +580,6 @@ void QtcProcess::start()
{
d->clearForRun();
if (!d->m_writeData.isEmpty()) {
connect(d->m_process, &ProcessInterface::started, this, [this] {
const qint64 bytesWritten = write(d->m_writeData);
QTC_CHECK(bytesWritten == d->m_writeData.size());
closeWriteChannel(); // FIXME: Is this good?
});
}
if (d->m_commandLine.executable().needsDevice()) {
QTC_ASSERT(s_deviceHooks.startProcessHook, return);
s_deviceHooks.startProcessHook(*this);
@@ -708,16 +698,6 @@ void QtcProcess::setDisableUnixTerminal()
d->m_process->setDisableUnixTerminal();
}
void QtcProcess::setKeepWriteChannelOpen()
{
d->m_keepStdInOpen = true;
}
bool QtcProcess::keepsWriteChannelOpen() const
{
return d->m_keepStdInOpen;
}
void QtcProcess::setStandardInputFile(const QString &inputFile)
{
d->m_process->setStandardInputFile(inputFile);
@@ -728,11 +708,6 @@ void QtcProcess::setRemoteProcessHooks(const DeviceProcessHooks &hooks)
s_deviceHooks = hooks;
}
void QtcProcess::setOpenMode(QIODevice::OpenMode mode)
{
d->m_openMode = mode;
}
bool QtcProcess::stopProcess()
{
if (state() == QProcess::NotRunning)
@@ -1004,14 +979,10 @@ void QtcProcess::kill()
qint64 QtcProcess::write(const QByteArray &input)
{
QTC_ASSERT(processMode() == ProcessMode::Writer, return -1);
return d->m_process->write(input);
}
void QtcProcess::closeWriteChannel()
{
d->m_process->closeWriteChannel();
}
void QtcProcess::close()
{
d->m_process->close();
@@ -1251,7 +1222,6 @@ void QtcProcess::setExitCodeInterpreter(const ExitCodeInterpreter &interpreter)
void QtcProcess::setWriteData(const QByteArray &writeData)
{
d->m_writeData = writeData;
setKeepWriteChannelOpen();
}
#ifdef QT_GUI_LIB
@@ -1276,13 +1246,6 @@ void QtcProcess::runBlocking()
ExecuteOnDestruction logResult([this] { qCDebug(processLog) << *this; });
if (d->m_processUserEvents) {
if (!d->m_writeData.isEmpty()) {
connect(d->m_process, &ProcessInterface::started, this, [this] {
write(d->m_writeData);
closeWriteChannel();
});
}
setOpenMode(d->m_writeData.isEmpty() ? QIODevice::ReadOnly : QIODevice::ReadWrite);
QtcProcess::start();
// On Windows, start failure is triggered immediately if the
@@ -1305,13 +1268,11 @@ void QtcProcess::runBlocking()
#endif
}
} else {
setOpenMode(QIODevice::ReadOnly);
QtcProcess::start();
if (!waitForStarted(d->m_maxHangTimerCount * 1000)) {
d->m_result = QtcProcess::StartFailed;
return;
}
closeWriteChannel();
if (!waitForFinished(d->m_maxHangTimerCount * 1000)) {
d->m_result = QtcProcess::Hang;
terminate();

View File

@@ -70,6 +70,8 @@ public:
QtcProcess(QObject *parent = nullptr);
~QtcProcess();
ProcessMode processMode() const;
enum Result {
// Finished successfully. Unless an ExitCodeInterpreter is set
// this corresponds to a return code 0.
@@ -131,8 +133,6 @@ public:
static void setRemoteProcessHooks(const DeviceProcessHooks &hooks);
void setOpenMode(QIODevice::OpenMode mode);
bool stopProcess();
bool readDataFromProcess(int timeoutS, QByteArray *stdOut, QByteArray *stdErr,
bool showTimeOutMessageBox);
@@ -185,12 +185,8 @@ public:
void kill();
qint64 write(const QByteArray &input);
void closeWriteChannel();
void close();
void setKeepWriteChannelOpen();
bool keepsWriteChannelOpen() const;
void setStandardInputFile(const QString &inputFile);
signals:

View File

@@ -1041,7 +1041,7 @@ void AndroidSdkManagerPrivate::getPendingLicense(SdkCmdFutureInterface &fi)
fi.setProgressValue(0);
AndroidSdkManager::OperationOutput result;
result.type = AndroidSdkManager::LicenseWorkflow;
QtcProcess licenseCommand;
QtcProcess licenseCommand(ProcessMode::Writer);
licenseCommand.setEnvironment(AndroidConfigurations::toolsEnvironment(m_config));
bool reviewingLicenses = false;
licenseCommand.setCommand(CommandLine(m_config.sdkManagerToolPath(), {"--licenses", sdkRootArg(m_config)}));

View File

@@ -653,7 +653,6 @@ void ExternalToolRunner::run()
}
}
m_process = new QtcProcess(this);
connect(m_process, &QtcProcess::started, this, &ExternalToolRunner::started);
connect(m_process, &QtcProcess::finished, this, &ExternalToolRunner::finished);
connect(m_process, &QtcProcess::errorOccurred, this, &ExternalToolRunner::error);
connect(m_process, &QtcProcess::readyReadStandardOutput,
@@ -669,14 +668,9 @@ void ExternalToolRunner::run()
? QOverload<const QString &>::of(MessageManager::writeDisrupting)
: QOverload<const QString &>::of(MessageManager::writeSilently);
write(tr("Starting external tool \"%1\"").arg(cmd.toUserOutput()));
m_process->start();
}
void ExternalToolRunner::started()
{
if (!m_resolvedInput.isEmpty())
m_process->write(m_resolvedInput.toLocal8Bit());
m_process->closeWriteChannel();
m_process->setWriteData(m_resolvedInput.toLocal8Bit());
m_process->start();
}
void ExternalToolRunner::finished()

View File

@@ -134,7 +134,6 @@ public:
QString errorString() const;
private:
void started();
void finished();
void error(QProcess::ProcessError error);
void readStandardOutput();

View File

@@ -176,7 +176,6 @@ void ExecuteFilter::runHeadCommand()
m_process->setWorkingDirectory(d.workingDirectory);
m_process->setCommand({fullPath, d.arguments, Utils::CommandLine::Raw});
m_process->start();
m_process->closeWriteChannel();
if (!m_process->waitForStarted(1000)) {
MessageManager::writeFlashing(
tr("Could not start process: %1.").arg(m_process->errorString()));

View File

@@ -109,7 +109,6 @@ SpotlightIterator::SpotlightIterator(const QStringList &command)
scheduleKillProcess();
m_waitForItems.wakeAll();
});
m_process->setOpenMode(QIODevice::ReadOnly);
m_process->start();
}

View File

@@ -105,6 +105,7 @@ static bool runPatchHelper(const QByteArray &input, const QString &workingDirect
QDir::toNativeSeparators(patch),
args.join(QLatin1Char(' '))));
patchProcess.setCommand({patch, args});
patchProcess.setWriteData(input);
patchProcess.start();
if (!patchProcess.waitForStarted()) {
MessageManager::writeFlashing(
@@ -113,10 +114,6 @@ static bool runPatchHelper(const QByteArray &input, const QString &workingDirect
return false;
}
patchProcess.write(input);
patchProcess.closeWriteChannel();
QByteArray stdOut;
QByteArray stdErr;
if (!patchProcess.readDataFromProcess(30, &stdOut, &stdErr, true)) {

View File

@@ -179,6 +179,7 @@ void addCdbOptionPages(QList<Core::IOptionsPage *> *opts)
#define QT_CREATOR_CDB_EXT "qtcreatorcdbext"
CdbEngine::CdbEngine() :
m_process(ProcessMode::Writer),
m_tokenPrefix("<token>"),
m_extensionCommandPrefix("!" QT_CREATOR_CDB_EXT ".")
{

View File

@@ -451,7 +451,6 @@ static QString findQtInstallPath(const FilePath &qmakePath)
qPrintable(proc.errorString()));
return QString();
}
proc.closeWriteChannel();
if (!proc.waitForFinished()) {
proc.stopProcess();
qWarning("%s: Timeout running '%s'.", Q_FUNC_INFO, qPrintable(qmakePath.toString()));

View File

@@ -145,6 +145,7 @@ const char tracepointCapturePropertyName[] = "GDB.TracepointCapture";
///////////////////////////////////////////////////////////////////////
GdbEngine::GdbEngine()
: m_gdbProc(ProcessMode::Writer)
{
setObjectName("GdbEngine");
setDebuggerName("GDB");
@@ -3851,7 +3852,6 @@ void GdbEngine::setupEngine()
if (rp.debugger.workingDirectory.isDir())
m_gdbProc.setWorkingDirectory(rp.debugger.workingDirectory);
m_gdbProc.setEnvironment(gdbEnv);
m_gdbProc.setKeepWriteChannelOpen();
m_gdbProc.start();
if (!m_gdbProc.waitForStarted()) {

View File

@@ -82,6 +82,7 @@ static int &currentToken()
///////////////////////////////////////////////////////////////////////
LldbEngine::LldbEngine()
: m_lldbProc(ProcessMode::Writer)
{
setObjectName("LldbEngine");
setDebuggerName("LLDB");

View File

@@ -122,6 +122,7 @@ private:
DockerDeviceProcess::DockerDeviceProcess(const QSharedPointer<const IDevice> &device,
QObject *parent)
: DeviceProcess(device, parent)
, m_process(ProcessMode::Writer)
{
}
@@ -1449,7 +1450,7 @@ void DockerDevice::runProcess(QtcProcess &process) const
CommandLine cmd{"docker", {"exec"}};
if (!workingDir.isEmpty())
cmd.addArgs({"-w", workingDir.path()});
if (process.keepsWriteChannelOpen())
if (process.processMode() == ProcessMode::Writer)
cmd.addArg("-i");
if (env.size() != 0 && d->m_accessible != DockerDevicePrivate::Accessible) {
process.unsetEnvironment();

View File

@@ -325,7 +325,6 @@ void QueryContext::start()
m_timer.start();
m_process.setCommand({m_binary, m_arguments});
m_process.start();
m_process.closeWriteChannel();
}
void QueryContext::errorTermination(const QString &msg)

View File

@@ -150,7 +150,6 @@ FetchContext::FetchContext(const QSharedPointer<GerritChange> &change,
m_watcher.setFuture(m_progress.future());
m_process.setWorkingDirectory(repository);
m_process.setEnvironment(GitClient::instance()->processEnvironment());
m_process.closeWriteChannel();
}
FetchContext::~FetchContext()
@@ -173,7 +172,6 @@ void FetchContext::start()
VcsBase::VcsOutputWindow::appendCommand(m_repository.toString(), {m_git, args});
m_process.setCommand({m_git, args});
m_process.start();
m_process.closeWriteChannel();
}
void FetchContext::processFinished()

View File

@@ -88,6 +88,7 @@ void BaseClientInterface::parseData(const QByteArray &data)
}
StdIOClientInterface::StdIOClientInterface()
: m_process(ProcessMode::Writer)
{
connect(&m_process, &QtcProcess::readyReadStandardError,
this, &StdIOClientInterface::readError);

View File

@@ -91,7 +91,6 @@ void PerforceChecker::start(const QString &binary, const QString &workingDirecto
m_process.setCommand({m_binary, args});
m_process.start();
m_process.closeWriteChannel();
// Timeout handling
m_timeOutMS = timeoutMS;
m_timedOut = false;

View File

@@ -1310,26 +1310,14 @@ PerforceResponse PerforcePluginPrivate::fullySynchronousProcess(const QString &w
PerforceResponse response;
process.setCommand({m_settings.p4BinaryPath.value(), args});
process.setWriteData(stdInput);
process.start();
if (stdInput.isEmpty())
process.closeWriteChannel();
if (!process.waitForStarted(3000)) {
response.error = true;
response.message = msgNotStarted(m_settings.p4BinaryPath.value());
return response;
}
if (!stdInput.isEmpty()) {
if (process.write(stdInput) == -1) {
process.stopProcess();
response.error = true;
response.message = tr("Unable to write input data to process %1: %2").
arg(QDir::toNativeSeparators(m_settings.p4BinaryPath.value()),
process.errorString());
return response;
}
process.closeWriteChannel();
}
QByteArray stdOut;
QByteArray stdErr;

View File

@@ -402,7 +402,6 @@ void ApplicationLauncherPrivate::start(const Runnable &runnable, const IDevice::
m_consoleProcess.start();
} else {
m_guiProcess.setCommand(cmdLine);
m_guiProcess.closeWriteChannel();
m_guiProcess.start();
}
} else {

View File

@@ -40,6 +40,7 @@ namespace Internal {
DesktopDeviceProcess::DesktopDeviceProcess(const QSharedPointer<const IDevice> &device,
QObject *parent)
: DeviceProcess(device, parent)
, m_process(ProcessMode::Writer)
{
connect(&m_process, &QtcProcess::errorOccurred, this, &DeviceProcess::error);
connect(&m_process, &QtcProcess::finished, this, &DeviceProcess::finished);

View File

@@ -1795,7 +1795,6 @@ static QByteArray runQmakeQuery(const FilePath &binary, const Environment &env,
QtcProcess process;
process.setEnvironment(env);
process.setOpenMode(QIODevice::ReadOnly);
process.setCommand({binary, {"-query"}});
process.start();

View File

@@ -662,7 +662,6 @@ bool VcsBaseSubmitEditor::runSubmitMessageCheckScript(const QString &checkScript
checkProcess.setWorkingDirectory(d->m_checkScriptWorkingDirectory);
checkProcess.setCommand({checkScript, {saver.filePath().toString()}});
checkProcess.start();
checkProcess.closeWriteChannel();
if (!checkProcess.waitForStarted()) {
*errorMessage = tr("The check script \"%1\" could not be started: %2").arg(checkScript, checkProcess.errorString());
return false;