mirror of
https://github.com/lubosz/overte.git
synced 2025-04-27 18:35:24 +02:00
98 lines
3.4 KiB
C++
98 lines
3.4 KiB
C++
//
|
|
// AssignmentClientMonitor.cpp
|
|
// assignment-client/src
|
|
//
|
|
// Created by Stephen Birarda on 1/10/2014.
|
|
// Copyright 2014 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include <signal.h>
|
|
|
|
#include <LogHandler.h>
|
|
#include <ShutdownEventListener.h>
|
|
|
|
#include "AssignmentClientMonitor.h"
|
|
|
|
const char* NUM_FORKS_PARAMETER = "-n";
|
|
|
|
const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor";
|
|
|
|
AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks) :
|
|
QCoreApplication(argc, argv)
|
|
{
|
|
// start the Logging class with the parent's target name
|
|
LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME);
|
|
|
|
// setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us
|
|
#ifdef _WIN32
|
|
installNativeEventFilter(&ShutdownEventListener::getInstance());
|
|
#else
|
|
ShutdownEventListener::getInstance();
|
|
#endif
|
|
|
|
_childArguments = arguments();
|
|
|
|
// remove the parameter for the number of forks so it isn't passed to the child forked processes
|
|
int forksParameterIndex = _childArguments.indexOf(NUM_FORKS_PARAMETER);
|
|
|
|
// this removes both the "-n" parameter and the number of forks passed
|
|
_childArguments.removeAt(forksParameterIndex);
|
|
_childArguments.removeAt(forksParameterIndex);
|
|
|
|
// use QProcess to fork off a process for each of the child assignment clients
|
|
for (int i = 0; i < numAssignmentClientForks; i++) {
|
|
spawnChildClient();
|
|
}
|
|
}
|
|
|
|
AssignmentClientMonitor::~AssignmentClientMonitor() {
|
|
stopChildProcesses();
|
|
}
|
|
|
|
void AssignmentClientMonitor::stopChildProcesses() {
|
|
|
|
QList<QPointer<QProcess> >::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<QProcess>(assignmentClient));
|
|
|
|
// make sure that the output from the child process appears in our output
|
|
assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels);
|
|
|
|
assignmentClient->start(applicationFilePath(), _childArguments);
|
|
|
|
// link the child processes' finished slot to our childProcessFinished slot
|
|
connect(assignmentClient, SIGNAL(finished(int, QProcess::ExitStatus)), this,
|
|
SLOT(childProcessFinished(int, QProcess::ExitStatus)));
|
|
|
|
qDebug() << "Spawned a child client with PID" << assignmentClient->pid();
|
|
}
|
|
|
|
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<QProcess>(qobject_cast<QProcess*>(sender()));
|
|
_childProcesses.removeOne(QPointer<QProcess>(qobject_cast<QProcess*>(sender())));
|
|
|
|
spawnChildClient();
|
|
}
|