From 98d7261c678ab4f4b02649b60c5f7032c4770cdc Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 26 Aug 2021 12:02:39 +0200 Subject: [PATCH] Assert that when stopping the launcher no QtcProcess exists Otherwise such a QtcProcess won't work properly anymore. Change-Id: I9eb7c8beb864a895a60c0e60ff394e74c35a0ebb Reviewed-by: hjk --- src/libs/utils/launchersocket.cpp | 36 ++++++++++++++++++++++++++----- src/libs/utils/launchersocket.h | 6 ++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/libs/utils/launchersocket.cpp b/src/libs/utils/launchersocket.cpp index e8a12329c70..6a5dd9f99d6 100644 --- a/src/libs/utils/launchersocket.cpp +++ b/src/libs/utils/launchersocket.cpp @@ -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"); } +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()) diff --git a/src/libs/utils/launchersocket.h b/src/libs/utils/launchersocket.h index 56dfa65e007..2d2f662fc10 100644 --- a/src/libs/utils/launchersocket.h +++ b/src/libs/utils/launchersocket.h @@ -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;