Move ProcessReaper into lib/utils

Reuse ProcessReaper inside process launcher.
Automatically reap all internal QProcesses of QtcProcess
(either direct child of QtcProcess in QProcessImpl
or indirectly inside process launcher).
Make ProcessReaper work again on QProcess instead of on
QtcProcess, so it may still be reused for non-QtcProcesses.

Change-Id: I950cac5cec28f17ae97fe474d6a4e48c01d6aaa2
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2021-09-06 14:48:08 +02:00
parent 72d52f3ac2
commit ace765c199
26 changed files with 142 additions and 203 deletions

View File

@@ -38,6 +38,7 @@
#include <utils/hostosinfo.h>
#include <utils/launcherinterface.h>
#include <utils/optional.h>
#include <utils/processreaper.h>
#include <utils/qtcsettings.h>
#include <utils/temporarydirectory.h>
@@ -534,6 +535,7 @@ int main(int argc, char **argv)
QCoreApplication::setOrganizationName(QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR));
QGuiApplication::setApplicationDisplayName(Core::Constants::IDE_DISPLAY_NAME);
Utils::ProcessReaper processReaper;
Utils::LauncherInterface::startLauncher();
auto cleanup = qScopeGuard([] { Utils::LauncherInterface::stopLauncher(); });

View File

@@ -121,6 +121,7 @@ add_qtc_library(Utils
portlist.cpp portlist.h
predicates.h
processhandle.cpp processhandle.h
processreaper.cpp processreaper.h
processutils.cpp processutils.h
progressindicator.cpp progressindicator.h
projectintropage.cpp projectintropage.h projectintropage.ui

View File

@@ -28,6 +28,7 @@
#include "filepath.h"
#include "launcherpackets.h"
#include "launchersocket.h"
#include "processreaper.h"
#include "qtcassert.h"
#include <QCoreApplication>
@@ -143,7 +144,7 @@ void LauncherInterfacePrivate::doStop()
m_process->disconnect();
m_socket->shutdown();
m_process->waitForFinished(3000);
m_process->deleteLater();
ProcessReaper::reap(m_process);
m_process = nullptr;
}

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -23,29 +23,26 @@
**
****************************************************************************/
#include "reaper.h"
#include "reaper_p.h"
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include "processreaper.h"
#include "qtcassert.h"
#include <QCoreApplication>
#include <QProcess>
#include <QThread>
#include <QTimer>
using namespace Utils;
namespace Core {
namespace Utils {
namespace Internal {
static ProcessReapers *d = nullptr;
static ProcessReaper *d = nullptr;
class ProcessReaper final : public QObject
class Reaper final : public QObject
{
public:
ProcessReaper(QtcProcess *p, int timeoutMs);
~ProcessReaper() final;
Reaper(QProcess *p, int timeoutMs);
~Reaper() final;
int timeoutMs() const;
bool isFinished() const;
@@ -53,28 +50,28 @@ public:
private:
mutable QTimer m_iterationTimer;
QtcProcess *m_process;
QProcess *m_process = nullptr;
int m_emergencyCounter = 0;
QProcess::ProcessState m_lastState = QProcess::NotRunning;
};
ProcessReaper::ProcessReaper(QtcProcess *p, int timeoutMs) : m_process(p)
Reaper::Reaper(QProcess *p, int timeoutMs) : m_process(p)
{
d->m_reapers.append(this);
m_iterationTimer.setInterval(timeoutMs);
m_iterationTimer.setSingleShot(true);
connect(&m_iterationTimer, &QTimer::timeout, this, &ProcessReaper::nextIteration);
connect(&m_iterationTimer, &QTimer::timeout, this, &Reaper::nextIteration);
QMetaObject::invokeMethod(this, &ProcessReaper::nextIteration, Qt::QueuedConnection);
QMetaObject::invokeMethod(this, &Reaper::nextIteration, Qt::QueuedConnection);
}
ProcessReaper::~ProcessReaper()
Reaper::~Reaper()
{
d->m_reapers.removeOne(this);
}
int ProcessReaper::timeoutMs() const
int Reaper::timeoutMs() const
{
const int remaining = m_iterationTimer.remainingTime();
if (remaining < 0)
@@ -83,12 +80,12 @@ int ProcessReaper::timeoutMs() const
return remaining;
}
bool ProcessReaper::isFinished() const
bool Reaper::isFinished() const
{
return !m_process;
}
void ProcessReaper::nextIteration()
void Reaper::nextIteration()
{
QProcess::ProcessState state = m_process ? m_process->state() : QProcess::NotRunning;
if (state == QProcess::NotRunning || m_emergencyCounter > 5) {
@@ -113,19 +110,23 @@ void ProcessReaper::nextIteration()
++m_emergencyCounter;
}
ProcessReapers::ProcessReapers()
} // namespace Internal
ProcessReaper::ProcessReaper()
{
d = this;
QTC_ASSERT(Internal::d == nullptr, return);
Internal::d = this;
}
ProcessReapers::~ProcessReapers()
ProcessReaper::~ProcessReaper()
{
QTC_ASSERT(Internal::d == this, return);
while (!m_reapers.isEmpty()) {
int alreadyWaited = 0;
QList<ProcessReaper *> toDelete;
QList<Internal::Reaper *> toDelete;
// push reapers along:
foreach (ProcessReaper *pr, m_reapers) {
for (Internal::Reaper *pr : qAsConst(m_reapers)) {
const int timeoutMs = pr->timeoutMs();
if (alreadyWaited < timeoutMs) {
const unsigned long toSleep = static_cast<unsigned long>(timeoutMs - alreadyWaited);
@@ -145,25 +146,30 @@ ProcessReapers::~ProcessReapers()
toDelete.clear();
}
d = nullptr;
Internal::d = nullptr;
}
} // namespace Internal
namespace Reaper {
void reap(QtcProcess *process, int timeoutMs)
void ProcessReaper::reap(QProcess *process, int timeoutMs)
{
if (!process)
return;
QTC_ASSERT(QThread::currentThread() == process->thread(), return);
process->disconnect();
process->setParent(nullptr);
if (process->state() == QProcess::NotRunning) {
process->deleteLater();
return;
} else {
process->kill();
}
// Neither can move object with a parent into a different thread
// nor reaping the process with a parent makes any sense.
process->setParent(nullptr);
if (process->thread() != qApp->thread()) {
process->moveToThread(qApp->thread());
if (process->thread() != QCoreApplication::instance()->thread()) {
process->moveToThread(QCoreApplication::instance()->thread());
QMetaObject::invokeMethod(process, [process, timeoutMs] {
reap(process, timeoutMs);
}); // will be queued
@@ -172,9 +178,8 @@ void reap(QtcProcess *process, int timeoutMs)
QTC_ASSERT(Internal::d, return);
new Internal::ProcessReaper(process, timeoutMs);
new Internal::Reaper(process, timeoutMs);
}
} // namespace Reaper
} // namespace Core
} // namespace Utils

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,25 +25,28 @@
#pragma once
#include "utils_global.h"
#include <QList>
namespace Core {
namespace Internal {
QT_BEGIN_NAMESPACE
class QProcess;
QT_END_NAMESPACE
class CorePlugin;
class ProcessReaper;
namespace Utils {
class ProcessReapers final
namespace Internal { class Reaper; }
class QTCREATOR_UTILS_EXPORT ProcessReaper final
{
public:
ProcessReaper();
~ProcessReaper();
static void reap(QProcess *process, int timeoutMs = 500);
private:
~ProcessReapers();
ProcessReapers();
QList<ProcessReaper *> m_reapers;
friend class CorePlugin;
friend class ProcessReaper;
QList<Internal::Reaper *> m_reapers;
friend class Internal::Reaper;
};
} // namespace Internal
} // namespace Core
} // namespace Utils

View File

@@ -31,6 +31,7 @@
#include "launcherinterface.h"
#include "launcherpackets.h"
#include "launchersocket.h"
#include "processreaper.h"
#include "qtcassert.h"
#include "stringutils.h"
@@ -278,86 +279,90 @@ class QProcessImpl : public ProcessInterface
public:
QProcessImpl(QObject *parent, ProcessMode processMode)
: ProcessInterface(parent, processMode)
, m_process(parent)
, m_process(new ProcessHelper(parent))
{
connect(&m_process, &QProcess::started,
connect(m_process, &QProcess::started,
this, &QProcessImpl::handleStarted);
connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &ProcessInterface::finished);
connect(&m_process, &QProcess::errorOccurred,
connect(m_process, &QProcess::errorOccurred,
this, &ProcessInterface::errorOccurred);
connect(&m_process, &QProcess::readyReadStandardOutput,
connect(m_process, &QProcess::readyReadStandardOutput,
this, &ProcessInterface::readyReadStandardOutput);
connect(&m_process, &QProcess::readyReadStandardError,
connect(m_process, &QProcess::readyReadStandardError,
this, &ProcessInterface::readyReadStandardError);
}
~QProcessImpl() override
{
ProcessReaper::reap(m_process);
}
QByteArray readAllStandardOutput() override { return m_process.readAllStandardOutput(); }
QByteArray readAllStandardError() override { return m_process.readAllStandardError(); }
QByteArray readAllStandardOutput() override { return m_process->readAllStandardOutput(); }
QByteArray readAllStandardError() override { return m_process->readAllStandardError(); }
void setProcessEnvironment(const QProcessEnvironment &environment) override
{ m_process.setProcessEnvironment(environment); }
{ m_process->setProcessEnvironment(environment); }
void setWorkingDirectory(const QString &dir) override
{ m_process.setWorkingDirectory(dir); }
{ m_process->setWorkingDirectory(dir); }
void start(const QString &program, const QStringList &arguments, const QByteArray &writeData) override
{
m_processStartHandler.setProcessMode(processMode());
m_processStartHandler.setWriteData(writeData);
if (isBelowNormalPriority())
m_processStartHandler.setBelowNormalPriority(&m_process);
m_processStartHandler.setNativeArguments(&m_process, nativeArguments());
m_processStartHandler.setBelowNormalPriority(m_process);
m_processStartHandler.setNativeArguments(m_process, nativeArguments());
if (isLowPriority())
m_process.setLowPriority();
m_process->setLowPriority();
if (isUnixTerminalDisabled())
m_process.setUnixTerminalDisabled();
m_process.start(program, arguments, m_processStartHandler.openMode());
m_processStartHandler.handleProcessStart(&m_process);
m_process->setUnixTerminalDisabled();
m_process->start(program, arguments, m_processStartHandler.openMode());
m_processStartHandler.handleProcessStart(m_process);
}
void terminate() override
{ m_process.terminate(); }
{ m_process->terminate(); }
void kill() override
{ m_process.kill(); }
{ m_process->kill(); }
void close() override
{ m_process.close(); }
{ m_process->close(); }
qint64 write(const QByteArray &data) override
{ return m_process.write(data); }
{ return m_process->write(data); }
void setStandardInputFile(const QString &fileName) override
{ m_process.setStandardInputFile(fileName); }
{ m_process->setStandardInputFile(fileName); }
void setProcessChannelMode(QProcess::ProcessChannelMode mode) override
{ m_process.setProcessChannelMode(mode); }
{ m_process->setProcessChannelMode(mode); }
QString program() const override
{ return m_process.program(); }
{ return m_process->program(); }
QProcess::ProcessError error() const override
{ return m_process.error(); }
{ return m_process->error(); }
QProcess::ProcessState state() const override
{ return m_process.state(); }
{ return m_process->state(); }
qint64 processId() const override
{ return m_process.processId(); }
{ return m_process->processId(); }
int exitCode() const override
{ return m_process.exitCode(); }
{ return m_process->exitCode(); }
QProcess::ExitStatus exitStatus() const override
{ return m_process.exitStatus(); }
{ return m_process->exitStatus(); }
QString errorString() const override
{ return m_process.errorString(); }
{ return m_process->errorString(); }
void setErrorString(const QString &str) override
{ m_process.setErrorString(str); }
{ m_process->setErrorString(str); }
bool waitForStarted(int msecs) override
{ return m_process.waitForStarted(msecs); }
{ return m_process->waitForStarted(msecs); }
bool waitForReadyRead(int msecs) override
{ return m_process.waitForReadyRead(msecs); }
{ return m_process->waitForReadyRead(msecs); }
bool waitForFinished(int msecs) override
{ return m_process.waitForFinished(msecs); }
{ return m_process->waitForFinished(msecs); }
private:
void handleStarted()
{
m_processStartHandler.handleProcessStarted(&m_process);
m_processStartHandler.handleProcessStarted(m_process);
emit started();
}
ProcessHelper m_process;
ProcessHelper *m_process;
ProcessStartHandler m_processStartHandler;
};

View File

@@ -84,6 +84,7 @@ SOURCES += \
$$PWD/json.cpp \
$$PWD/portlist.cpp \
$$PWD/processhandle.cpp \
$$PWD/processreaper.cpp \
$$PWD/processutils.cpp \
$$PWD/appmainwindow.cpp \
$$PWD/basetreeview.cpp \
@@ -222,6 +223,7 @@ HEADERS += \
$$PWD/runextensions.h \
$$PWD/portlist.h \
$$PWD/processhandle.h \
$$PWD/processreaper.h \
$$PWD/processutils.h \
$$PWD/appmainwindow.h \
$$PWD/basetreeview.h \

View File

@@ -218,6 +218,8 @@ Project {
"portlist.h",
"processhandle.cpp",
"processhandle.h",
"processreaper.cpp",
"processreaper.h",
"processutils.cpp",
"processutils.h",
"progressindicator.cpp",

View File

@@ -39,7 +39,6 @@
#include <android/androidconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/reaper.h>
#include <cppeditor/cppeditorconstants.h>
#include <cppeditor/cppprojectupdater.h>
#include <cppeditor/generatedcodemodelsupport.h>

View File

@@ -28,7 +28,6 @@
#include "cmakeparser.h"
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/reaper.h>
#include <projectexplorer/buildsystem.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/taskhub.h>
@@ -57,11 +56,7 @@ CMakeProcess::CMakeProcess()
CMakeProcess::~CMakeProcess()
{
if (m_process) {
m_process->disconnect();
Core::Reaper::reap(m_process.release());
}
m_process.reset();
m_parser.flush();
if (m_future) {

View File

@@ -135,7 +135,6 @@ add_qtc_plugin(Core
progressmanager/progressbar.cpp progressmanager/progressbar.h
progressmanager/progressmanager.cpp progressmanager/progressmanager.h progressmanager/progressmanager_p.h
progressmanager/progressview.cpp progressmanager/progressview.h
reaper.cpp reaper.h reaper_p.h
rightpane.cpp rightpane.h
settingsdatabase.cpp settingsdatabase.h
shellcommand.cpp shellcommand.h

View File

@@ -32,7 +32,6 @@
#include "iwizardfactory.h"
#include "mainwindow.h"
#include "modemanager.h"
#include "reaper_p.h"
#include "themechooser.h"
#include <coreplugin/actionmanager/actionmanager.h>
@@ -96,13 +95,11 @@ CorePlugin::CorePlugin()
qRegisterMetaType<Utils::CommandLine>();
qRegisterMetaType<Utils::FilePath>();
m_instance = this;
m_reaper = new ProcessReapers;
setupSystemEnvironment();
}
CorePlugin::~CorePlugin()
{
delete m_reaper;
IWizardFactory::destroyFeatureProvider();
Find::destroy();

View File

@@ -44,7 +44,6 @@ namespace Internal {
class EditMode;
class MainWindow;
class Locator;
class ProcessReapers;
class CorePlugin : public ExtensionSystem::IPlugin
{
@@ -93,7 +92,6 @@ private:
MainWindow *m_mainWindow = nullptr;
EditMode *m_editMode = nullptr;
Locator *m_locator = nullptr;
ProcessReapers *m_reaper = nullptr;
Utils::Environment m_startupSystemEnvironment;
Utils::EnvironmentItems m_environmentChanges;
};

View File

@@ -54,7 +54,6 @@ SOURCES += corejsextensions.cpp \
progressmanager/progressview.cpp \
progressmanager/progressbar.cpp \
progressmanager/futureprogress.cpp \
reaper.cpp \
coreplugin.cpp \
modemanager.cpp \
basefilewizard.cpp \
@@ -161,8 +160,6 @@ HEADERS += corejsextensions.h \
progressmanager/progressbar.h \
progressmanager/futureprogress.h \
progressmanager/progressmanager.h \
reaper.h \
reaper_p.h \
icontext.h \
icore.h \
imode.h \

View File

@@ -144,9 +144,6 @@ Project {
"plugindialog.h",
"plugininstallwizard.cpp",
"plugininstallwizard.h",
"reaper.cpp",
"reaper.h",
"reaper_p.h",
"rightpane.cpp",
"rightpane.h",
"settingsdatabase.cpp",

View File

@@ -27,7 +27,6 @@
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/reaper.h>
#include <utils/macroexpander.h>
#include <utils/qtcassert.h>
@@ -199,12 +198,7 @@ void ExecuteFilter::removeProcess()
return;
m_taskQueue.dequeue();
m_process->disconnect();
if (m_process->state() == QProcess::NotRunning)
m_process->deleteLater();
else
Reaper::reap(m_process);
delete m_process;
m_process = nullptr;
}

View File

@@ -28,7 +28,6 @@
#include "../messagemanager.h"
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/reaper.h>
#include <utils/algorithm.h>
#include <utils/commandline.h>
#include <utils/environment.h>
@@ -156,10 +155,7 @@ void SpotlightIterator::killProcess()
QMutexLocker lock(&m_mutex);
m_finished = true;
m_waitForItems.wakeAll();
if (m_process->state() == QProcess::NotRunning)
m_process.reset();
else
Reaper::reap(m_process.release());
m_process.reset();
}
void SpotlightIterator::ensureNext()

View File

@@ -1,38 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "core_global.h"
namespace Utils { class QtcProcess; }
namespace Core {
namespace Reaper {
CORE_EXPORT void reap(Utils::QtcProcess *p, int timeoutMs = 500);
} // namespace Reaper
} // namespace Core

View File

@@ -34,8 +34,6 @@
#include "target.h"
#include "task.h"
#include <coreplugin/reaper.h>
#include <utils/fileutils.h>
#include <utils/outputformatter.h>
#include <utils/qtcassert.h>
@@ -255,7 +253,7 @@ void AbstractProcessStep::setLowPriority()
void AbstractProcessStep::doCancel()
{
Core::Reaper::reap(d->m_process.release());
d->m_process.reset();
}
ProcessParameters *AbstractProcessStep::processParameters()

View File

@@ -11,6 +11,10 @@ add_qtc_executable(qtcreator_processlauncher
processlauncher-main.cpp
${UTILSDIR}/launcherpackets.cpp
${UTILSDIR}/launcherpackets.h
${UTILSDIR}/processreaper.cpp
${UTILSDIR}/processreaper.h
${UTILSDIR}/processutils.cpp
${UTILSDIR}/processutils.h
${UTILSDIR}/qtcassert.cpp
${UTILSDIR}/qtcassert.h
)

View File

@@ -26,12 +26,12 @@
#include "launchersockethandler.h"
#include "launcherlogging.h"
#include "processreaper.h"
#include "processutils.h"
#include <QCoreApplication>
#include <QLocalSocket>
#include <QProcess>
#include <QTimer>
namespace Utils {
namespace Internal {
@@ -41,43 +41,13 @@ class Process : public ProcessHelper
Q_OBJECT
public:
Process(quintptr token, QObject *parent = nullptr) :
ProcessHelper(parent), m_token(token), m_stopTimer(new QTimer(this))
{
m_stopTimer->setSingleShot(true);
connect(m_stopTimer, &QTimer::timeout, this, &Process::cancel);
}
void cancel()
{
if (state() == QProcess::NotRunning) {
deleteLater();
return;
}
switch (m_stopState) {
case StopState::Inactive:
m_stopState = StopState::Terminating;
m_stopTimer->start(3000);
terminate();
break;
case StopState::Terminating:
m_stopState = StopState::Killing;
m_stopTimer->start(3000);
kill();
break;
case StopState::Killing:
m_stopState = StopState::Inactive;
deleteLater(); // TODO: employ something like Core::Reaper here
break;
}
}
ProcessHelper(parent), m_token(token) { }
quintptr token() const { return m_token; }
ProcessStartHandler *processStartHandler() { return &m_processStartHandler; }
private:
const quintptr m_token;
QTimer * const m_stopTimer;
enum class StopState { Inactive, Terminating, Killing } m_stopState = StopState::Inactive;
ProcessStartHandler m_processStartHandler;
};
@@ -97,7 +67,7 @@ LauncherSocketHandler::~LauncherSocketHandler()
m_socket->close();
}
for (auto it = m_processes.cbegin(); it != m_processes.cend(); ++it)
it.value()->disconnect();
ProcessReaper::reap(it.value());
}
void LauncherSocketHandler::start()
@@ -269,13 +239,15 @@ void LauncherSocketHandler::handleStopPacket()
{
Process * const process = m_processes.value(m_packetParser.token());
if (!process) {
logWarn("got stop request for unknown process");
// This can happen when the process finishes on its own at about the same time the client
// sends the request. In this case the process was already deleted.
logDebug("got stop request for unknown process");
return;
}
if (process->state() == QProcess::NotRunning) {
// This can happen if the process finishes on its own at about the same time the client
// sends the request.
logDebug("got stop request when process was not running");
// This shouldn't happen, since as soon as process finishes or error occurrs
// the process is being removed.
logWarn("got stop request when process was not running");
} else {
// We got the client request to stop the starting / running process.
// We report process exit to the client.
@@ -331,11 +303,7 @@ void LauncherSocketHandler::removeProcess(quintptr token)
Process *process = it.value();
m_processes.erase(it);
process->disconnect();
if (process->state() != QProcess::NotRunning)
process->cancel();
else
process->deleteLater();
ProcessReaper::reap(process);
}
Process *LauncherSocketHandler::senderProcess() const

View File

@@ -25,6 +25,7 @@
#include "launcherlogging.h"
#include "launchersockethandler.h"
#include "processreaper.h"
#include <QtCore/qcoreapplication.h>
#include <QtCore/qtimer.h>
@@ -51,6 +52,7 @@ int main(int argc, char *argv[])
return 1;
}
Utils::ProcessReaper processReaper;
Utils::Internal::LauncherSocketHandler launcher(app.arguments().constLast());
QTimer::singleShot(0, &launcher, &Utils::Internal::LauncherSocketHandler::start);
return app.exec();

View File

@@ -13,11 +13,15 @@ HEADERS += \
launcherlogging.h \
launchersockethandler.h \
$$UTILS_DIR/launcherpackets.h \
$$UTILS_DIR/processutils.h
$$UTILS_DIR/processreaper.h \
$$UTILS_DIR/processutils.h \
$$UTILS_DIR/qtcassert.h
SOURCES += \
launcherlogging.cpp \
launchersockethandler.cpp \
processlauncher-main.cpp \
$$UTILS_DIR/launcherpackets.cpp \
$$UTILS_DIR/processutils.cpp
$$UTILS_DIR/processreaper.cpp \
$$UTILS_DIR/processutils.cpp \
$$UTILS_DIR/qtcassert.cpp

View File

@@ -23,8 +23,12 @@ QtcTool {
files: [
"launcherpackets.cpp",
"launcherpackets.h",
"processreaper.cpp",
"processreaper.h",
"processutils.cpp",
"processutils.h",
"qtcassert.cpp",
"qtcassert.h",
]
}
}

View File

@@ -27,6 +27,7 @@
#include <utils/hostosinfo.h>
#include <utils/launcherinterface.h>
#include <utils/porting.h>
#include <utils/processreaper.h>
#include <utils/qtcprocess.h>
#include <utils/stringutils.h>
@@ -203,6 +204,7 @@ private slots:
private:
void iteratorEditsHelper(OsType osType);
Utils::ProcessReaper processReaper;
Environment envWindows;
Environment envLinux;

View File

@@ -30,6 +30,7 @@
#include <sqliteglobal.h>
#include <utils/launcherinterface.h>
#include <utils/processreaper.h>
#include <utils/temporarydirectory.h>
#include <QGuiApplication>
@@ -60,6 +61,7 @@ int main(int argc, char *argv[])
Sqlite::Database::activateLogging();
QGuiApplication application(argc, argv);
Utils::ProcessReaper processReaper;
Utils::LauncherInterface::startLauncher(qApp->applicationDirPath() + '/'
+ QLatin1String(TEST_RELATIVE_LIBEXEC_PATH));
auto cleanup = qScopeGuard([] { Utils::LauncherInterface::stopLauncher(); });