98 lines · 3.4 KB · C++
RawDownload
////  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();}