summaryrefslogtreecommitdiffstats
path: root/wayland
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2017-09-28 14:31:17 +0200
committerHolger Freyther <holger+qt@freyther.de>2017-11-09 13:03:47 +0000
commite5047dc19d84dc45eef92c2c59bab52637f092d6 (patch)
tree7c328ba315806add1e0926d07d286e72d7cd4db1 /wayland
parenta84980d2cde1f62e574446729d48dd0b29804933 (diff)
processlauncher: Fix crashing on destruction with running apps
The democompositor would crash because the QProcess will be deleted from within ~QObject and then emit a signal which will access the partially destructed WaylandProcessLauncher. Iterate through the list and disconnect the slots and then delete the QProcess before the ~QObject is ran. An alternative would be to iterate the m_appStates and just block the signals of the QProcess. This might be more future proof (e.g. another signal being connected) but can impact other signal/slot connections as well. Change-Id: Id6c19dbe0c3070a131b28365584f06fb7c6014b3 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'wayland')
-rw-r--r--wayland/democompositor/processlauncher.cpp16
-rw-r--r--wayland/democompositor/processlauncher.h3
2 files changed, 15 insertions, 4 deletions
diff --git a/wayland/democompositor/processlauncher.cpp b/wayland/democompositor/processlauncher.cpp
index 2fb75c7..bd78de6 100644
--- a/wayland/democompositor/processlauncher.cpp
+++ b/wayland/democompositor/processlauncher.cpp
@@ -72,6 +72,13 @@ WaylandProcessLauncher::WaylandProcessLauncher(QObject *parent)
WaylandProcessLauncher::~WaylandProcessLauncher()
{
+ for (auto state : m_appStates) {
+ state.process->disconnect(state.finishedConn);
+ state.process->disconnect(state.errorOccurredConn);
+ state.process->disconnect(state.startedConn);
+ delete state.process;
+ }
+ m_appStates.clear();
}
QVariant WaylandProcessLauncher::appStateForPid(int pid) const
@@ -107,18 +114,19 @@ void WaylandProcessLauncher::launch(const AppEntry &entry)
QProcess *process = new QProcess(this);
process->setProcessChannelMode(QProcess::ForwardedChannels);
- AppState state{process, entry};
+ QMetaObject::Connection conn;
+ AppState state{process, entry, conn, conn, conn};
m_appStates.push_back(state);
/* handle potential errors and life cycle */
- connect(process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
+ state.finishedConn = connect(process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
[state, this](int exitCode, QProcess::ExitStatus status) {
qCDebug(procs) << "AppEntry finished" << state.appEntry.executableName << exitCode << status;
emit appFinished(state, exitCode, status);
m_appStates.removeOne(state);
state.process->deleteLater();
});
- connect(process, &QProcess::errorOccurred,
+ state.errorOccurredConn = connect(process, &QProcess::errorOccurred,
[state, this](QProcess::ProcessError err) {
qCDebug(procs) << "AppEntry error occurred" << state.appEntry.executableName << err;
@@ -130,7 +138,7 @@ void WaylandProcessLauncher::launch(const AppEntry &entry)
emit appNotStarted(state);
state.process->deleteLater();
});
- connect(process, &QProcess::started,
+ state.startedConn = connect(process, &QProcess::started,
[state, this]() {
qCDebug(procs) << "AppEntry started" << state.appEntry.executableName;
emit appStarted(state);
diff --git a/wayland/democompositor/processlauncher.h b/wayland/democompositor/processlauncher.h
index f21be98..3d30c07 100644
--- a/wayland/democompositor/processlauncher.h
+++ b/wayland/democompositor/processlauncher.h
@@ -70,6 +70,9 @@ class AppState {
public:
QProcess *process;
AppEntry appEntry;
+ QMetaObject::Connection finishedConn;
+ QMetaObject::Connection errorOccurredConn;
+ QMetaObject::Connection startedConn;
};
class WaylandProcessLauncher : public QObject