From dac980d43386902fc34161aefd6eef2a0deff1c1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 19 Nov 2014 16:40:19 -0800 Subject: [PATCH] have AssignmentClientMonitor catch SIGTERM and cleanup --- .../src/AssignmentClientMonitor.cpp | 39 +++++++++++++++++++ .../src/AssignmentClientMonitor.h | 4 ++ 2 files changed, 43 insertions(+) diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 02a4ff04f0..358b963b4b 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include "AssignmentClientMonitor.h" @@ -17,9 +19,21 @@ const char* NUM_FORKS_PARAMETER = "-n"; const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor"; +void signalHandler(int param){ + // get the qApp and cast it to an AssignmentClientMonitor + AssignmentClientMonitor* app = qobject_cast(qApp); + + // tell it to stop the child processes and then go down + app->stopChildProcesses(); + app->quit(); +} + AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks) : QCoreApplication(argc, argv) { + // be a signal handler for SIGTERM so we can stop our children when we get it + signal(SIGTERM, signalHandler); + // start the Logging class with the parent's target name LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME); @@ -38,9 +52,29 @@ AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int num } } +void AssignmentClientMonitor::stopChildProcesses() { + + QList >::Iterator it = _childProcesses.begin(); + while (it != _childProcesses.end()) { + if (!it->isNull()) { + qDebug() << "Monitor is terminating child process" << it->data(); + + // don't re-spawn this child when it goes down + disconnect(it->data(), 0, this, 0); + + it->data()->terminate(); + it->data()->waitForFinished(); + } + + it = _childProcesses.erase(it); + } +} + void AssignmentClientMonitor::spawnChildClient() { QProcess *assignmentClient = new QProcess(this); + _childProcesses.append(QPointer(assignmentClient)); + // make sure that the output from the child process appears in our output assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels); @@ -55,5 +89,10 @@ void AssignmentClientMonitor::spawnChildClient() { void AssignmentClientMonitor::childProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) { qDebug("Replacing dead child assignment client with a new one"); + + // remove the old process from our list of child processes + qDebug() << "need to remove" << QPointer(qobject_cast(sender())); + _childProcesses.removeOne(QPointer(qobject_cast(sender()))); + spawnChildClient(); } diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index 1df08a345e..9dbfcc495a 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -13,6 +13,7 @@ #define hifi_AssignmentClientMonitor_h #include +#include #include #include @@ -23,10 +24,13 @@ class AssignmentClientMonitor : public QCoreApplication { Q_OBJECT public: AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks); + + void stopChildProcesses(); private slots: void childProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); private: void spawnChildClient(); + QList > _childProcesses; QStringList _childArguments; };