diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 63738d2d91..83cac6d9bb 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -190,7 +190,7 @@ int main(int argc, const char* argv[]) { int exitCode; { - RunningMarker runningMarker(nullptr, RUNNING_MARKER_FILENAME); + RunningMarker runningMarker(RUNNING_MARKER_FILENAME); bool runningMarkerExisted = runningMarker.fileExists(); runningMarker.writeRunningMarkerFile(); @@ -199,14 +199,11 @@ int main(int argc, const char* argv[]) { bool serverContentPathOptionIsSet = parser.isSet(serverContentPathOption); QString serverContentPath = serverContentPathOptionIsSet ? parser.value(serverContentPathOption) : QString(); if (runServer) { - SandboxUtils::runLocalSandbox(serverContentPath, true, RUNNING_MARKER_FILENAME, noUpdater); + SandboxUtils::runLocalSandbox(serverContentPath, true, noUpdater); } Application app(argc, const_cast(argv), startupTime, runningMarkerExisted); - // Now that the main event loop is setup, launch running marker thread - runningMarker.startRunningMarker(); - // If we failed the OpenGLVersion check, log it. if (override) { auto accountManager = DependencyManager::get(); diff --git a/libraries/networking/src/SandboxUtils.cpp b/libraries/networking/src/SandboxUtils.cpp index d816f7ebee..4a348b0662 100644 --- a/libraries/networking/src/SandboxUtils.cpp +++ b/libraries/networking/src/SandboxUtils.cpp @@ -52,9 +52,8 @@ bool readStatus(QByteArray statusData) { return false; } -void runLocalSandbox(QString contentPath, bool autoShutdown, QString runningMarkerName, bool noUpdater) { +void runLocalSandbox(QString contentPath, bool autoShutdown, bool noUpdater) { QString serverPath = "./server-console/server-console.exe"; - qCDebug(networking) << "Running marker path is: " << runningMarkerName; qCDebug(networking) << "Server path is: " << serverPath; qCDebug(networking) << "autoShutdown: " << autoShutdown; qCDebug(networking) << "noUpdater: " << noUpdater; @@ -74,8 +73,8 @@ void runLocalSandbox(QString contentPath, bool autoShutdown, QString runningMark } if (autoShutdown) { - QString interfaceRunningStateFile = RunningMarker::getMarkerFilePath(runningMarkerName); - args << "--shutdownWatcher" << interfaceRunningStateFile; + auto pid = QCoreApplication::applicationPid(); + args << "--shutdownWith" << QString::number(pid); } if (noUpdater) { diff --git a/libraries/networking/src/SandboxUtils.h b/libraries/networking/src/SandboxUtils.h index 42484b8edf..370b28e1b0 100644 --- a/libraries/networking/src/SandboxUtils.h +++ b/libraries/networking/src/SandboxUtils.h @@ -21,7 +21,7 @@ namespace SandboxUtils { QNetworkReply* getStatus(); bool readStatus(QByteArray statusData); - void runLocalSandbox(QString contentPath, bool autoShutdown, QString runningMarkerName, bool noUpdater); + void runLocalSandbox(QString contentPath, bool autoShutdown, bool noUpdater); }; #endif // hifi_SandboxUtils_h diff --git a/libraries/shared/src/RunningMarker.cpp b/libraries/shared/src/RunningMarker.cpp index 0c1fd06df8..cb7b39320c 100644 --- a/libraries/shared/src/RunningMarker.cpp +++ b/libraries/shared/src/RunningMarker.cpp @@ -13,44 +13,16 @@ #include #include -#include -#include -#include "NumericalConstants.h" #include "PathUtils.h" -RunningMarker::RunningMarker(QObject* parent, QString name) : - _parent(parent), +RunningMarker::RunningMarker(QString name) : _name(name) { } -void RunningMarker::startRunningMarker() { - static const int RUNNING_STATE_CHECK_IN_MSECS = MSECS_PER_SECOND; - - // start the nodeThread so its event loop is running - _runningMarkerThread = new QThread(_parent); - _runningMarkerThread->setObjectName("Running Marker Thread"); - _runningMarkerThread->start(); - - writeRunningMarkerFile(); // write the first file, even before timer - - _runningMarkerTimer = new QTimer(); - QObject::connect(_runningMarkerTimer, &QTimer::timeout, [=](){ - writeRunningMarkerFile(); - }); - _runningMarkerTimer->start(RUNNING_STATE_CHECK_IN_MSECS); - - // put the time on the thread - _runningMarkerTimer->moveToThread(_runningMarkerThread); -} - RunningMarker::~RunningMarker() { deleteRunningMarkerFile(); - QMetaObject::invokeMethod(_runningMarkerTimer, "stop", Qt::BlockingQueuedConnection); - _runningMarkerThread->quit(); - _runningMarkerTimer->deleteLater(); - _runningMarkerThread->deleteLater(); } bool RunningMarker::fileExists() const { @@ -77,8 +49,3 @@ void RunningMarker::deleteRunningMarkerFile() { QString RunningMarker::getFilePath() const { return QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + _name; } - -QString RunningMarker::getMarkerFilePath(QString name) { - return QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + name; -} - diff --git a/libraries/shared/src/RunningMarker.h b/libraries/shared/src/RunningMarker.h index f9c8e72d37..ae7c550660 100644 --- a/libraries/shared/src/RunningMarker.h +++ b/libraries/shared/src/RunningMarker.h @@ -12,21 +12,14 @@ #ifndef hifi_RunningMarker_h #define hifi_RunningMarker_h -#include #include -class QThread; -class QTimer; - class RunningMarker { public: - RunningMarker(QObject* parent, QString name); + RunningMarker(QString name); ~RunningMarker(); - void startRunningMarker(); - QString getFilePath() const; - static QString getMarkerFilePath(QString name); bool fileExists() const; @@ -34,10 +27,7 @@ public: void deleteRunningMarkerFile(); private: - QObject* _parent { nullptr }; QString _name; - QThread* _runningMarkerThread { nullptr }; - QTimer* _runningMarkerTimer { nullptr }; }; #endif // hifi_RunningMarker_h diff --git a/server-console/src/main.js b/server-console/src/main.js index 98bda9a10f..408a17bd56 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -821,6 +821,17 @@ for (var key in trayIcons) { const notificationIcon = path.join(__dirname, '../resources/console-notification.png'); +function isProcessRunning(pid) { + try { + // Sending a signal of 0 is effectively a NOOP. + // If sending the signal is successful, kill will return true. + // If the process is not running, an exception will be thrown. + return process.kill(pid, 0); + } catch (e) { + } + return false; +} + function onContentLoaded() { // Disable splash window for now. // maybeShowSplash(); @@ -882,31 +893,18 @@ function onContentLoaded() { startInterface(); } - // If we were launched with the shutdownWatcher option, then we need to watch for the interface app - // shutting down. The interface app will regularly update a running state file which we will check. - // If the file doesn't exist or stops updating for a significant amount of time, we will shut down. - if (argv.shutdownWatcher) { - log.debug("Shutdown watcher requested... argv.shutdownWatcher:", argv.shutdownWatcher); - var MAX_TIME_SINCE_EDIT = 5000; // 5 seconds between updates - var firstAttemptToCheck = new Date().getTime(); - var shutdownWatchInterval = setInterval(function(){ - var stats = fs.stat(argv.shutdownWatcher, function(err, stats) { - if (err) { - var sinceFirstCheck = new Date().getTime() - firstAttemptToCheck; - if (sinceFirstCheck > MAX_TIME_SINCE_EDIT) { - log.debug("Running state file is missing, assume interface has shutdown... shutting down snadbox."); - forcedShutdown(); - clearTimeout(shutdownWatchInterval); - } - } else { - var sinceEdit = new Date().getTime() - stats.mtime.getTime(); - if (sinceEdit > MAX_TIME_SINCE_EDIT) { - log.debug("Running state of interface hasn't updated in MAX time... shutting down."); - forcedShutdown(); - clearTimeout(shutdownWatchInterval); - } - } - }); + // If we were launched with the shutdownWith option, then we need to shutdown when that process (pid) + // is no longer running. + if (argv.shutdownWith) { + let pid = argv.shutdownWith; + console.log("Shutting down with process: ", pid); + let checkProcessInterval = setInterval(function() { + let isRunning = isProcessRunning(pid); + if (!isRunning) { + log.debug("Watched process is no longer running, shutting down"); + clearTimeout(checkProcessInterval); + forcedShutdown(); + } }, 1000); } }