diff --git a/src/gamecenter/gamecenterdaemon.cpp b/src/gamecenter/gamecenterdaemon.cpp index b3678dd..5f688d5 100644 --- a/src/gamecenter/gamecenterdaemon.cpp +++ b/src/gamecenter/gamecenterdaemon.cpp @@ -833,6 +833,15 @@ void GameCenterDaemon::handleSystemdUnitPropertiesChanged(const QDBusObjectPath auto sit = m_sessions.find(sessionId); if (sit == m_sessions.end()) { + unwatchSystemdUnit({}, unitPath); + + for (auto nameIt = m_unitNameToSessionId.begin(); nameIt != m_unitNameToSessionId.end();) { + if (nameIt.value() == sessionId) { + nameIt = m_unitNameToSessionId.erase(nameIt); + } else { + ++nameIt; + } + } return; } @@ -1570,8 +1579,31 @@ QString GameCenterDaemon::launchMonitored(const QVariantMap &launchSpec, const Q QVariantMap finalState = sessionToVariantMap(it.value(), stopping ? QStringLiteral("Stopped") : QStringLiteral("Failed")); if (!it.value().unitName.isEmpty()) { - m_systemd.stopUnit(it.value().unitName); - unwatchSystemdUnit(it.value().unitName, it.value().unitPath); + const QString unitName = it.value().unitName; + const QDBusObjectPath unitPath = it.value().unitPath; + const uint mainPid = it.value().mainPid; + + const QDBusReply stopReply = m_systemd.stopUnit(unitName); + if (!stopReply.isValid() && stopReply.error().name() != QLatin1String("org.freedesktop.systemd1.NoSuchUnit")) { + QList pids; + if (!unitPath.path().isEmpty()) { + pids = m_systemd.scopePids(unitPath); + } + if (pids.isEmpty() && it.value().process && it.value().process->processId() > 0) { + pids = {static_cast(it.value().process->processId())}; + } + if (pids.isEmpty() && mainPid > 0) { + pids = {mainPid}; + } + if (!pids.isEmpty()) { + terminatePids(pids); + QTimer::singleShot(5000, this, [pids]() { + killPids(pids); + }); + } + } + + unwatchSystemdUnit(unitName, unitPath); } if (it.value().scanner) { @@ -1643,8 +1675,25 @@ void GameCenterDaemon::attachPidsToSession(const QString &sessionId, const QList }; if (!it.value().unitName.isEmpty()) { - m_systemd.stopUnit(it.value().unitName); - unwatchSystemdUnit(it.value().unitName, it.value().unitPath); + const QString staleUnitName = it.value().unitName; + const QDBusObjectPath staleUnitPath = it.value().unitPath; + + const QDBusReply stopReply = m_systemd.stopUnit(staleUnitName); + if (!stopReply.isValid() && stopReply.error().name() != QLatin1String("org.freedesktop.systemd1.NoSuchUnit")) { + QList stalePids; + if (!staleUnitPath.path().isEmpty()) { + stalePids = m_systemd.scopePids(staleUnitPath); + } + if (stalePids.isEmpty()) { + stalePids = pids; + } + terminatePids(stalePids); + QTimer::singleShot(5000, this, [stalePids]() { + killPids(stalePids); + }); + } + + unwatchSystemdUnit(staleUnitName, staleUnitPath); } QVariantMap finalState = sessionToVariantMap(it.value(), QStringLiteral("Failed"));