Assert that when stopping the launcher no QtcProcess exists

Otherwise such a QtcProcess won't work properly anymore.

Change-Id: I9eb7c8beb864a895a60c0e60ff394e74c35a0ebb
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2021-08-26 12:02:39 +02:00
parent 98de1c5544
commit 98d7261c67
2 changed files with 37 additions and 5 deletions

View File

@@ -270,7 +270,6 @@ void CallerHandle::appendSignal(LauncherSignal *launcherSignal)
QProcess::ProcessState CallerHandle::state() const
{
QTC_ASSERT(isCalledFromCallersThread(), return QProcess::NotRunning);
return m_processState;
}
@@ -336,21 +335,23 @@ void CallerHandle::start(const QString &program, const QStringList &arguments, c
emit errorOccurred(m_error);
return;
}
auto startWhenRunning = [&program, &oldProgram = m_command] {
qWarning() << "Trying to start" << program << "while" << oldProgram
<< "is still running for the same QtcProcess instance."
<< "The current call will be ignored.";
};
QTC_ASSERT(m_processState == QProcess::NotRunning, startWhenRunning(); return);
m_command = program;
m_arguments = arguments;
m_writeData = writeData;
auto processLauncherNotStarted = [&program] {
qWarning() << "Trying to start" << program << "while process launcher wasn't started yet.";
};
QTC_ASSERT(LauncherInterface::isStarted(), processLauncherNotStarted());
QMutexLocker locker(&m_mutex);
m_command = program;
m_arguments = arguments;
m_writeData = writeData;
m_processState = QProcess::Starting;
StartProcessPacket *p = new StartProcessPacket(m_token);
p->command = m_command;
@@ -414,10 +415,16 @@ QProcess::ProcessError CallerHandle::error() const
QString CallerHandle::program() const
{
QTC_ASSERT(isCalledFromCallersThread(), return {});
QMutexLocker locker(&m_mutex);
return m_command;
}
QStringList CallerHandle::arguments() const
{
QMutexLocker locker(&m_mutex);
return m_arguments;
}
void CallerHandle::setStandardInputFile(const QString &fileName)
{
QTC_ASSERT(isCalledFromCallersThread(), return);
@@ -757,6 +764,25 @@ LauncherSocket::LauncherSocket(QObject *parent) : QObject(parent)
qRegisterMetaType<quintptr>("quintptr");
}
LauncherSocket::~LauncherSocket()
{
QMutexLocker locker(&m_mutex);
auto displayHandles = [&handles = m_handles] {
qWarning() << "Destroying process launcher while" << handles.count()
<< "processes are still alive. The following processes are still alive:";
for (LauncherHandle *handle : handles) {
CallerHandle *callerHandle = handle->callerHandle();
if (callerHandle->state() != QProcess::NotRunning) {
qWarning() << " " << callerHandle->program() << callerHandle->arguments()
<< "in thread" << (void *)callerHandle->thread();
} else {
qWarning() << " Not running process in thread" << (void *)callerHandle->thread();
}
}
};
QTC_ASSERT(m_handles.isEmpty(), displayHandles());
}
void LauncherSocket::sendData(const QByteArray &data)
{
if (!isReady())

View File

@@ -84,6 +84,7 @@ public:
// Called from launcher's thread exclusively.
void appendSignal(LauncherSignal *launcherSignal);
// Called from caller's or launcher's thread.
QProcess::ProcessState state() const;
void cancel();
@@ -101,7 +102,10 @@ public:
qint64 write(const QByteArray &data);
QProcess::ProcessError error() const;
// Called from caller's or launcher's thread.
QString program() const;
// Called from caller's or launcher's thread.
QStringList arguments() const;
void setStandardInputFile(const QString &fileName);
void setProcessChannelMode(QProcess::ProcessChannelMode mode);
void setProcessEnvironment(const QProcessEnvironment &environment);
@@ -257,6 +261,8 @@ signals:
private:
// Called from caller's thread, moved to launcher's thread.
LauncherSocket(QObject *parent = nullptr);
// Called from launcher's thread exclusively.
~LauncherSocket() override;
// Called from launcher's thread exclusively.
LauncherHandle *handleForToken(quintptr token) const;