Make all objects created by QtcProcess children of it

Sometimes after creating QtcProcess we move it into a different
thread. In this case we should move all the children, too.
Without parent-child relation all the children will stay in the
old thread.

Change-Id: Ibde44d6153092a155dd2d200a7116a046910dddc
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Jarek Kobus
2021-09-02 17:03:49 +02:00
parent a454b3dc23
commit f7aa963a07
6 changed files with 28 additions and 23 deletions

View File

@@ -255,12 +255,13 @@ void LauncherInterface::sendData(const QByteArray &data)
s_instance->m_private->socket()->sendData(data); s_instance->m_private->socket()->sendData(data);
} }
Utils::Internal::CallerHandle *LauncherInterface::registerHandle(quintptr token, ProcessMode mode) Utils::Internal::CallerHandle *LauncherInterface::registerHandle(QObject *parent, quintptr token,
ProcessMode mode)
{ {
QMutexLocker locker(&s_instanceMutex); QMutexLocker locker(&s_instanceMutex);
QTC_ASSERT(s_instance != nullptr, return nullptr); QTC_ASSERT(s_instance != nullptr, return nullptr);
return s_instance->m_private->socket()->registerHandle(token, mode); return s_instance->m_private->socket()->registerHandle(parent, token, mode);
} }
void LauncherInterface::unregisterHandle(quintptr token) void LauncherInterface::unregisterHandle(quintptr token)

View File

@@ -58,7 +58,8 @@ private:
static bool isStarted(); static bool isStarted();
static bool isReady(); static bool isReady();
static void sendData(const QByteArray &data); static void sendData(const QByteArray &data);
static Utils::Internal::CallerHandle *registerHandle(quintptr token, ProcessMode mode); static Utils::Internal::CallerHandle *registerHandle(QObject *parent, quintptr token,
ProcessMode mode);
static void unregisterHandle(quintptr token); static void unregisterHandle(quintptr token);
LauncherInterface(); LauncherInterface();

View File

@@ -810,14 +810,14 @@ void LauncherSocket::sendData(const QByteArray &data)
QMetaObject::invokeMethod(this, &LauncherSocket::handleRequests); QMetaObject::invokeMethod(this, &LauncherSocket::handleRequests);
} }
CallerHandle *LauncherSocket::registerHandle(quintptr token, ProcessMode mode) CallerHandle *LauncherSocket::registerHandle(QObject *parent, quintptr token, ProcessMode mode)
{ {
QTC_ASSERT(!isCalledFromLaunchersThread(), return nullptr); QTC_ASSERT(!isCalledFromLaunchersThread(), return nullptr);
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
if (m_handles.contains(token)) if (m_handles.contains(token))
return nullptr; // TODO: issue a warning return nullptr; // TODO: issue a warning
CallerHandle *callerHandle = new CallerHandle(token, mode); CallerHandle *callerHandle = new CallerHandle(parent, token, mode);
LauncherHandle *launcherHandle = new LauncherHandle(token, mode); LauncherHandle *launcherHandle = new LauncherHandle(token, mode);
callerHandle->setLauncherHandle(launcherHandle); callerHandle->setLauncherHandle(launcherHandle);
launcherHandle->setCallerHandle(callerHandle); launcherHandle->setCallerHandle(callerHandle);

View File

@@ -67,7 +67,8 @@ public:
Finished Finished
}; };
Q_ENUM(SignalType) Q_ENUM(SignalType)
CallerHandle(quintptr token, ProcessMode mode) : QObject(), m_token(token), m_processMode(mode) {} CallerHandle(QObject *parent, quintptr token, ProcessMode mode)
: QObject(parent), m_token(token), m_processMode(mode) {}
~CallerHandle() override; ~CallerHandle() override;
LauncherHandle *launcherHandle() const { return m_launcherHandle; } LauncherHandle *launcherHandle() const { return m_launcherHandle; }
@@ -252,7 +253,7 @@ public:
void sendData(const QByteArray &data); void sendData(const QByteArray &data);
// Called from caller's thread exclusively. // Called from caller's thread exclusively.
CallerHandle *registerHandle(quintptr token, ProcessMode mode); CallerHandle *registerHandle(QObject *parent, quintptr token, ProcessMode mode);
void unregisterHandle(quintptr token); void unregisterHandle(quintptr token);
signals: signals:

View File

@@ -54,7 +54,7 @@ private:
class ProcessHelper : public QProcess class ProcessHelper : public QProcess
{ {
public: public:
ProcessHelper(QObject *parent = nullptr) : QProcess(parent) ProcessHelper(QObject *parent) : QProcess(parent)
{ {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && defined(Q_OS_UNIX) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && defined(Q_OS_UNIX)
setChildProcessModifier([this] { setupChildProcess_impl(); }); setChildProcessModifier([this] { setupChildProcess_impl(); });

View File

@@ -214,8 +214,8 @@ class ProcessInterface : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
ProcessInterface(ProcessMode processMode) ProcessInterface(QObject *parent, ProcessMode processMode)
: QObject() : QObject(parent)
, m_processMode(processMode) {} , m_processMode(processMode) {}
virtual QByteArray readAllStandardOutput() = 0; virtual QByteArray readAllStandardOutput() = 0;
@@ -276,7 +276,9 @@ private:
class QProcessImpl : public ProcessInterface class QProcessImpl : public ProcessInterface
{ {
public: public:
QProcessImpl(ProcessMode processMode) : ProcessInterface(processMode) QProcessImpl(QObject *parent, ProcessMode processMode)
: ProcessInterface(parent, processMode)
, m_process(parent)
{ {
connect(&m_process, &QProcess::started, connect(&m_process, &QProcess::started,
this, &QProcessImpl::handleStarted); this, &QProcessImpl::handleStarted);
@@ -369,10 +371,10 @@ class ProcessLauncherImpl : public ProcessInterface
{ {
Q_OBJECT Q_OBJECT
public: public:
ProcessLauncherImpl(ProcessMode processMode) ProcessLauncherImpl(QObject *parent, ProcessMode processMode)
: ProcessInterface(processMode), m_token(uniqueToken()) : ProcessInterface(parent, processMode), m_token(uniqueToken())
{ {
m_handle = LauncherInterface::registerHandle(token(), processMode); m_handle = LauncherInterface::registerHandle(parent, token(), processMode);
connect(m_handle, &CallerHandle::errorOccurred, connect(m_handle, &CallerHandle::errorOccurred,
this, &ProcessInterface::errorOccurred); this, &ProcessInterface::errorOccurred);
connect(m_handle, &CallerHandle::started, connect(m_handle, &CallerHandle::started,
@@ -388,6 +390,7 @@ public:
{ {
cancel(); cancel();
LauncherInterface::unregisterHandle(token()); LauncherInterface::unregisterHandle(token());
m_handle = nullptr;
} }
QByteArray readAllStandardOutput() override { return m_handle->readAllStandardOutput(); } QByteArray readAllStandardOutput() override { return m_handle->readAllStandardOutput(); }
@@ -448,11 +451,12 @@ void ProcessLauncherImpl::cancel()
m_handle->cancel(); m_handle->cancel();
} }
static ProcessInterface *newProcessInstance(QtcProcess::ProcessImpl processImpl, ProcessMode mode) static ProcessInterface *newProcessInstance(QObject *parent, QtcProcess::ProcessImpl processImpl,
ProcessMode mode)
{ {
if (processImpl == QtcProcess::QProcessImpl) if (processImpl == QtcProcess::QProcessImpl)
return new QProcessImpl(mode); return new QProcessImpl(parent, mode);
return new ProcessLauncherImpl(mode); return new ProcessLauncherImpl(parent, mode);
} }
class QtcProcessPrivate : public QObject class QtcProcessPrivate : public QObject
@@ -461,7 +465,10 @@ public:
explicit QtcProcessPrivate(QtcProcess *parent, explicit QtcProcessPrivate(QtcProcess *parent,
QtcProcess::ProcessImpl processImpl, QtcProcess::ProcessImpl processImpl,
ProcessMode processMode) ProcessMode processMode)
: q(parent), m_process(newProcessInstance(processImpl, processMode)), m_processMode(processMode) : QObject(parent)
, q(parent)
, m_process(newProcessInstance(parent, processImpl, processMode))
, m_processMode(processMode)
{ {
connect(m_process, &ProcessInterface::started, connect(m_process, &ProcessInterface::started,
q, &QtcProcess::started); q, &QtcProcess::started);
@@ -477,11 +484,6 @@ public:
m_timer.setInterval(1000); m_timer.setInterval(1000);
} }
~QtcProcessPrivate()
{
delete m_process;
}
void handleReadyReadStandardOutput() void handleReadyReadStandardOutput()
{ {
m_stdOut.append(m_process->readAllStandardOutput()); m_stdOut.append(m_process->readAllStandardOutput());