From 366ce69e6649892825b192614ad85983cc609cb5 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 13 Jul 2017 13:19:40 -0700 Subject: [PATCH 1/2] Add info on how the child AC finished --- .../src/AssignmentClientMonitor.cpp | 21 ++++++++++++++++--- .../src/AssignmentClientMonitor.h | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 070034d54b..5539d6a0bb 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -91,9 +91,22 @@ void AssignmentClientMonitor::simultaneousWaitOnChildren(int waitMsecs) { } } -void AssignmentClientMonitor::childProcessFinished(qint64 pid) { +void AssignmentClientMonitor::childProcessFinished(qint64 pid, int exitCode, QProcess::ExitStatus exitStatus) { + auto message = "Child process " + QString::number(pid) + " has %1 with exit code " + QString::number(exitCode) + "."; + if (_childProcesses.remove(pid)) { - qDebug() << "Child process" << pid << "has finished. Removed from internal map."; + message.append(" Removed from internal map."); + } else { + message.append(" Could not find process in internal map."); + } + + switch (exitStatus) { + case QProcess::NormalExit: + qDebug() << qPrintable(message.arg("returned")); + break; + case QProcess::CrashExit: + qCritical() << qPrintable(message.arg("crashed")); + break; } } @@ -221,7 +234,9 @@ void AssignmentClientMonitor::spawnChildClient() { auto pid = assignmentClient->processId(); // make sure we hear that this process has finished when it does connect(assignmentClient, static_cast(&QProcess::finished), - this, [this, pid]() { childProcessFinished(pid); }); + this, [this, pid](int exitCode, QProcess::ExitStatus exitStatus) { + childProcessFinished(pid, exitCode, exitStatus); + }); qDebug() << "Spawned a child client with PID" << assignmentClient->processId(); diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index a7f69a559b..8848d503ae 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -44,7 +44,7 @@ public: void stopChildProcesses(); private slots: void checkSpares(); - void childProcessFinished(qint64 pid); + void childProcessFinished(qint64 pid, int exitCode, QProcess::ExitStatus exitStatus); void handleChildStatusPacket(QSharedPointer message); bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url, bool skipSubHandler = false) override; From 2d246d25637edc69902a8ebe0ac2d639ca523cfb Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 13 Jul 2017 13:34:50 -0700 Subject: [PATCH 2/2] Implement shutdown with parent for Mac and Linux --- libraries/shared/src/SharedUtil.cpp | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 58b8aead45..99bdfc4d90 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -47,6 +47,7 @@ extern "C" FILE * __cdecl __iob_func(void) { #include #include #include +#include #include #include #include @@ -1077,14 +1078,20 @@ void setMaxCores(uint8_t maxCores) { #endif } -#ifdef Q_OS_WIN -VOID CALLBACK parentDiedCallback(PVOID lpParameter, BOOLEAN timerOrWaitFired) { - if (!timerOrWaitFired && qApp) { +void quitWithParentProcess() { + if (qApp) { qDebug() << "Parent process died, quitting"; qApp->quit(); } } +#ifdef Q_OS_WIN +VOID CALLBACK parentDiedCallback(PVOID lpParameter, BOOLEAN timerOrWaitFired) { + if (!timerOrWaitFired) { + quitWithParentProcess(); + } +} + void watchParentProcess(int parentPID) { DWORD processID = parentPID; HANDLE procHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID); @@ -1092,8 +1099,17 @@ void watchParentProcess(int parentPID) { HANDLE newHandle; RegisterWaitForSingleObject(&newHandle, procHandle, parentDiedCallback, NULL, INFINITE, WT_EXECUTEONLYONCE); } -#else +#elif defined(Q_OS_MAC) || defined(Q_OS_LINUX) void watchParentProcess(int parentPID) { - qWarning() << "Parent PID option not implemented on this plateform"; + auto timer = new QTimer(qApp); + timer->setInterval(MSECS_PER_SECOND); + QObject::connect(timer, &QTimer::timeout, qApp, [parentPID]() { + auto ppid = getppid(); + if (parentPID != ppid) { + // If the PPID changed, then that means our parent process died. + quitWithParentProcess(); + } + }); + timer->start(); } -#endif // Q_OS_WIN \ No newline at end of file +#endif