forked from qt-creator/qt-creator
QtcProcess: Make reaper timeout customizable
Add a setter and getter for reaper timeout. This makes it possible to customize the timeout for the reaper after which it should call kill() when previous terminate() was unsuccessful. This setting is also used for QtcProcess::stop(). Change-Id: I653a3ad107ae4173bb8254c85cfc07886bf6a9c6 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -69,7 +69,8 @@ void StartProcessPacket::doSerialize(QDataStream &stream) const
|
|||||||
<< nativeArguments
|
<< nativeArguments
|
||||||
<< lowPriority
|
<< lowPriority
|
||||||
<< unixTerminalDisabled
|
<< unixTerminalDisabled
|
||||||
<< useCtrlCStub;
|
<< useCtrlCStub
|
||||||
|
<< reaperTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartProcessPacket::doDeserialize(QDataStream &stream)
|
void StartProcessPacket::doDeserialize(QDataStream &stream)
|
||||||
@@ -88,7 +89,8 @@ void StartProcessPacket::doDeserialize(QDataStream &stream)
|
|||||||
>> nativeArguments
|
>> nativeArguments
|
||||||
>> lowPriority
|
>> lowPriority
|
||||||
>> unixTerminalDisabled
|
>> unixTerminalDisabled
|
||||||
>> useCtrlCStub;
|
>> useCtrlCStub
|
||||||
|
>> reaperTimeout;
|
||||||
processMode = Utils::ProcessMode(processModeInt);
|
processMode = Utils::ProcessMode(processModeInt);
|
||||||
processChannelMode = QProcess::ProcessChannelMode(processChannelModeInt);
|
processChannelMode = QProcess::ProcessChannelMode(processChannelModeInt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ public:
|
|||||||
bool lowPriority = false;
|
bool lowPriority = false;
|
||||||
bool unixTerminalDisabled = false;
|
bool unixTerminalDisabled = false;
|
||||||
bool useCtrlCStub = false;
|
bool useCtrlCStub = false;
|
||||||
|
int reaperTimeout = 500;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void doSerialize(QDataStream &stream) const override;
|
void doSerialize(QDataStream &stream) const override;
|
||||||
|
|||||||
@@ -288,6 +288,7 @@ void CallerHandle::start(const QString &program, const QStringList &arguments)
|
|||||||
p.lowPriority = m_setup->m_lowPriority;
|
p.lowPriority = m_setup->m_lowPriority;
|
||||||
p.unixTerminalDisabled = m_setup->m_unixTerminalDisabled;
|
p.unixTerminalDisabled = m_setup->m_unixTerminalDisabled;
|
||||||
p.useCtrlCStub = m_setup->m_useCtrlCStub;
|
p.useCtrlCStub = m_setup->m_useCtrlCStub;
|
||||||
|
p.reaperTimeout = m_setup->m_reaperTimeout;
|
||||||
sendPacket(p);
|
sendPacket(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public:
|
|||||||
QString m_standardInputFile;
|
QString m_standardInputFile;
|
||||||
QString m_nativeArguments; // internal, dependent on specific code path
|
QString m_nativeArguments; // internal, dependent on specific code path
|
||||||
|
|
||||||
|
int m_reaperTimeout = 500; // in ms
|
||||||
bool m_abortOnMetaChars = true;
|
bool m_abortOnMetaChars = true;
|
||||||
bool m_runAsRoot = false;
|
bool m_runAsRoot = false;
|
||||||
bool m_lowPriority = false;
|
bool m_lowPriority = false;
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ public:
|
|||||||
emit readyRead({}, m_process->readAllStandardError());
|
emit readyRead({}, m_process->readAllStandardError());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
~QProcessImpl() final { ProcessReaper::reap(m_process); }
|
~QProcessImpl() final { ProcessReaper::reap(m_process, m_setup.m_reaperTimeout); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qint64 write(const QByteArray &data) final { return m_process->write(data); }
|
qint64 write(const QByteArray &data) final { return m_process->write(data); }
|
||||||
@@ -1166,6 +1166,16 @@ QVariantHash QtcProcess::extraData() const
|
|||||||
return d->m_setup.m_extraData;
|
return d->m_setup.m_extraData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtcProcess::setReaperTimeout(int msecs)
|
||||||
|
{
|
||||||
|
d->m_setup.m_reaperTimeout = msecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QtcProcess::reaperTimeout() const
|
||||||
|
{
|
||||||
|
return d->m_setup.m_reaperTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
void QtcProcess::setRemoteProcessHooks(const DeviceProcessHooks &hooks)
|
void QtcProcess::setRemoteProcessHooks(const DeviceProcessHooks &hooks)
|
||||||
{
|
{
|
||||||
s_deviceHooks = hooks;
|
s_deviceHooks = hooks;
|
||||||
@@ -1501,12 +1511,16 @@ void QtcProcess::close()
|
|||||||
d->clearForRun();
|
d->clearForRun();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtcProcess::stop(int killTimeout)
|
/*
|
||||||
|
Calls terminate() directly and after a delay of reaperTimeout() it calls kill()
|
||||||
|
if the process is still running.
|
||||||
|
*/
|
||||||
|
void QtcProcess::stop()
|
||||||
{
|
{
|
||||||
if (state() == QProcess::NotRunning)
|
if (state() == QProcess::NotRunning)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
d->sendControlSignal(ControlSignal::Terminate, killTimeout);
|
d->sendControlSignal(ControlSignal::Terminate, d->m_process->m_setup.m_reaperTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QtcProcess::locateBinary(const QString &binary)
|
QString QtcProcess::locateBinary(const QString &binary)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public:
|
|||||||
void interrupt();
|
void interrupt();
|
||||||
void kickoffProcess();
|
void kickoffProcess();
|
||||||
void close();
|
void close();
|
||||||
void stop(int killTimeout = 500);
|
void stop();
|
||||||
|
|
||||||
QByteArray readAllStandardOutput();
|
QByteArray readAllStandardOutput();
|
||||||
QByteArray readAllStandardError();
|
QByteArray readAllStandardError();
|
||||||
@@ -131,6 +131,9 @@ public:
|
|||||||
void setExtraData(const QVariantHash &extraData);
|
void setExtraData(const QVariantHash &extraData);
|
||||||
QVariantHash extraData() const;
|
QVariantHash extraData() const;
|
||||||
|
|
||||||
|
void setReaperTimeout(int msecs);
|
||||||
|
int reaperTimeout() const;
|
||||||
|
|
||||||
static void setRemoteProcessHooks(const DeviceProcessHooks &hooks);
|
static void setRemoteProcessHooks(const DeviceProcessHooks &hooks);
|
||||||
|
|
||||||
// TODO: Some usages of this method assume that Starting phase is also a running state
|
// TODO: Some usages of this method assume that Starting phase is also a running state
|
||||||
|
|||||||
@@ -411,6 +411,7 @@ void TerminalImpl::start()
|
|||||||
d->m_process.setEnvironment(m_setup.m_environment);
|
d->m_process.setEnvironment(m_setup.m_environment);
|
||||||
d->m_process.setCommand({FilePath::fromString(terminal.command), allArgs});
|
d->m_process.setCommand({FilePath::fromString(terminal.command), allArgs});
|
||||||
d->m_process.setProcessImpl(m_setup.m_processImpl);
|
d->m_process.setProcessImpl(m_setup.m_processImpl);
|
||||||
|
d->m_process.setReaperTimeout(m_setup.m_reaperTimeout);
|
||||||
d->m_process.start();
|
d->m_process.start();
|
||||||
if (!d->m_process.waitForStarted()) {
|
if (!d->m_process.waitForStarted()) {
|
||||||
const QString msg = tr("Cannot start the terminal emulator \"%1\", change the setting in the "
|
const QString msg = tr("Cannot start the terminal emulator \"%1\", change the setting in the "
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ void DockerProcessImpl::start()
|
|||||||
m_process.setProcessImpl(m_setup.m_processImpl);
|
m_process.setProcessImpl(m_setup.m_processImpl);
|
||||||
m_process.setProcessMode(m_setup.m_processMode);
|
m_process.setProcessMode(m_setup.m_processMode);
|
||||||
m_process.setTerminalMode(m_setup.m_terminalMode);
|
m_process.setTerminalMode(m_setup.m_terminalMode);
|
||||||
|
m_process.setReaperTimeout(m_setup.m_reaperTimeout);
|
||||||
m_process.setWriteData(m_setup.m_writeData);
|
m_process.setWriteData(m_setup.m_writeData);
|
||||||
m_process.setProcessChannelMode(m_setup.m_processChannelMode);
|
m_process.setProcessChannelMode(m_setup.m_processChannelMode);
|
||||||
m_process.setExtraData(m_setup.m_extraData);
|
m_process.setExtraData(m_setup.m_extraData);
|
||||||
|
|||||||
@@ -738,6 +738,7 @@ void SshProcessInterfacePrivate::doStart()
|
|||||||
m_process.setProcessImpl(q->m_setup.m_processImpl);
|
m_process.setProcessImpl(q->m_setup.m_processImpl);
|
||||||
m_process.setProcessMode(q->m_setup.m_processMode);
|
m_process.setProcessMode(q->m_setup.m_processMode);
|
||||||
m_process.setTerminalMode(q->m_setup.m_terminalMode);
|
m_process.setTerminalMode(q->m_setup.m_terminalMode);
|
||||||
|
m_process.setReaperTimeout(q->m_setup.m_reaperTimeout);
|
||||||
m_process.setWriteData(q->m_setup.m_writeData);
|
m_process.setWriteData(q->m_setup.m_writeData);
|
||||||
// TODO: what about other fields from m_setup?
|
// TODO: what about other fields from m_setup?
|
||||||
SshParameters::setupSshEnvironment(&m_process);
|
SshParameters::setupSshEnvironment(&m_process);
|
||||||
|
|||||||
@@ -44,9 +44,12 @@ public:
|
|||||||
ProcessHelper(parent), m_token(token) { }
|
ProcessHelper(parent), m_token(token) { }
|
||||||
|
|
||||||
quintptr token() const { return m_token; }
|
quintptr token() const { return m_token; }
|
||||||
|
void setReaperTimeout(int msecs) { m_reaperTimeout = msecs; };
|
||||||
|
int reaperTimeout() const { return m_reaperTimeout; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const quintptr m_token;
|
const quintptr m_token;
|
||||||
|
int m_reaperTimeout = 500;
|
||||||
};
|
};
|
||||||
|
|
||||||
LauncherSocketHandler::LauncherSocketHandler(QString serverPath, QObject *parent)
|
LauncherSocketHandler::LauncherSocketHandler(QString serverPath, QObject *parent)
|
||||||
@@ -208,6 +211,7 @@ void LauncherSocketHandler::handleStartPacket()
|
|||||||
if (packet.unixTerminalDisabled)
|
if (packet.unixTerminalDisabled)
|
||||||
process->setUnixTerminalDisabled();
|
process->setUnixTerminalDisabled();
|
||||||
process->setUseCtrlCStub(packet.useCtrlCStub);
|
process->setUseCtrlCStub(packet.useCtrlCStub);
|
||||||
|
process->setReaperTimeout(packet.reaperTimeout);
|
||||||
process->start(packet.command, packet.arguments, handler->openMode());
|
process->start(packet.command, packet.arguments, handler->openMode());
|
||||||
handler->handleProcessStart();
|
handler->handleProcessStart();
|
||||||
}
|
}
|
||||||
@@ -289,7 +293,7 @@ void LauncherSocketHandler::removeProcess(quintptr token)
|
|||||||
|
|
||||||
Process *process = it.value();
|
Process *process = it.value();
|
||||||
m_processes.erase(it);
|
m_processes.erase(it);
|
||||||
ProcessReaper::reap(process);
|
ProcessReaper::reap(process, process->reaperTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
Reference in New Issue
Block a user