mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
auto shutdown of sandbox when interface quits
This commit is contained in:
parent
fb47b42ea5
commit
d46170bec0
12 changed files with 329 additions and 84 deletions
|
@ -94,6 +94,7 @@
|
|||
#include <RenderShadowTask.h>
|
||||
#include <RenderDeferredTask.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <SandboxUtils.h>
|
||||
#include <SceneScriptingInterface.h>
|
||||
#include <ScriptEngines.h>
|
||||
#include <ScriptCache.h>
|
||||
|
@ -415,8 +416,6 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset";
|
||||
bool suppressPrompt = cmdOptionExists(argc, const_cast<const char**>(argv), SUPPRESS_SETTINGS_RESET);
|
||||
bool previousSessionCrashed = CrashHandler::checkForResetSettings(suppressPrompt);
|
||||
CrashHandler::writeRunningMarkerFiler();
|
||||
qAddPostRoutine(CrashHandler::deleteRunningMarkerFile);
|
||||
|
||||
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
|
||||
DependencyManager::registerInheritance<AvatarHashMap, AvatarManager>();
|
||||
|
@ -504,8 +503,11 @@ Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context);
|
|||
|
||||
Setting::Handle<int> sessionRunTime{ "sessionRunTime", 0 };
|
||||
|
||||
Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||
Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bool runServer, QString runServerPathOption) :
|
||||
QApplication(argc, argv),
|
||||
_shouldRunServer(runServer),
|
||||
_runServerPath(runServerPathOption),
|
||||
_runningMarker(this, RUNNING_MARKER_FILENAME),
|
||||
_window(new MainWindow(desktop())),
|
||||
_sessionRunTimer(startupTimer),
|
||||
_previousSessionCrashed(setupEssentials(argc, argv)),
|
||||
|
@ -529,7 +531,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
_maxOctreePPS(maxOctreePacketsPerSecond.get()),
|
||||
_lastFaceTrackerUpdate(0)
|
||||
{
|
||||
|
||||
_runningMarker.startRunningMarker();
|
||||
|
||||
PluginContainer* pluginContainer = dynamic_cast<PluginContainer*>(this); // set the container for any plugins that care
|
||||
PluginManager::getInstance()->setContainer(pluginContainer);
|
||||
|
@ -575,6 +577,31 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
qCDebug(interfaceapp) << "[VERSION] We will use DEVELOPMENT global services.";
|
||||
#endif
|
||||
|
||||
|
||||
bool wantsSandboxRunning = shouldRunServer();
|
||||
bool determinedSandboxState = false;
|
||||
bool sandboxRunning = false;
|
||||
SandboxUtils sandboxUtils;
|
||||
sandboxUtils.ifLocalSandboxRunningElse([&]() {
|
||||
qDebug() << "Home sandbox appears to be running.....";
|
||||
determinedSandboxState = true;
|
||||
sandboxRunning = true;
|
||||
}, [&]() {
|
||||
qDebug() << "Home sandbox does not appear to be running....";
|
||||
determinedSandboxState = true;
|
||||
sandboxRunning = false;
|
||||
if (wantsSandboxRunning) {
|
||||
QString contentPath = getRunServerPath();
|
||||
SandboxUtils::runLocalSandbox(contentPath, true, RUNNING_MARKER_FILENAME);
|
||||
}
|
||||
});
|
||||
|
||||
quint64 MAX_WAIT_TIME = USECS_PER_SECOND * 4;
|
||||
auto startWaiting = usecTimestampNow();
|
||||
while (!determinedSandboxState && (usecTimestampNow() - startWaiting <= MAX_WAIT_TIME)) {
|
||||
QCoreApplication::processEvents();
|
||||
usleep(USECS_PER_MSEC * 50); // 20hz
|
||||
}
|
||||
|
||||
_bookmarks = new Bookmarks(); // Before setting up the menu
|
||||
|
||||
|
@ -1299,7 +1326,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
const QString TUTORIAL_PATH = "/tutorial_begin";
|
||||
|
||||
if (shouldGoToTutorial) {
|
||||
DependencyManager::get<AddressManager>()->ifLocalSandboxRunningElse([=]() {
|
||||
sandboxUtils.ifLocalSandboxRunningElse([=]() {
|
||||
qDebug() << "Home sandbox appears to be running, going to Home.";
|
||||
DependencyManager::get<AddressManager>()->goToLocalSandbox(TUTORIAL_PATH);
|
||||
}, [=]() {
|
||||
|
@ -1324,7 +1351,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
// If this is a first run we short-circuit the address passed in
|
||||
if (isFirstRun) {
|
||||
if (hasHMDAndHandControllers) {
|
||||
DependencyManager::get<AddressManager>()->ifLocalSandboxRunningElse([=]() {
|
||||
sandboxUtils.ifLocalSandboxRunningElse([=]() {
|
||||
qDebug() << "Home sandbox appears to be running, going to Home.";
|
||||
DependencyManager::get<AddressManager>()->goToLocalSandbox();
|
||||
}, [=]() {
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include <ThreadSafeValueCache.h>
|
||||
#include <shared/FileLogger.h>
|
||||
|
||||
#include <RunningMarker.h>
|
||||
|
||||
#include "avatar/MyAvatar.h"
|
||||
#include "Bookmarks.h"
|
||||
#include "Camera.h"
|
||||
|
@ -87,6 +89,8 @@ static const UINT UWM_SHOW_APPLICATION =
|
|||
RegisterWindowMessage("UWM_SHOW_APPLICATION_{71123FD6-3DA8-4DC1-9C27-8A12A6250CBA}_" + qgetenv("USERNAME"));
|
||||
#endif
|
||||
|
||||
static const QString RUNNING_MARKER_FILENAME = "Interface.running";
|
||||
|
||||
class Application;
|
||||
#if defined(qApp)
|
||||
#undef qApp
|
||||
|
@ -103,7 +107,16 @@ class Application : public QApplication,
|
|||
// TODO? Get rid of those
|
||||
friend class OctreePacketProcessor;
|
||||
|
||||
private:
|
||||
bool _shouldRunServer { false };
|
||||
QString _runServerPath;
|
||||
RunningMarker _runningMarker;
|
||||
|
||||
public:
|
||||
// startup related getter/setters
|
||||
bool shouldRunServer() const { return _shouldRunServer; }
|
||||
bool hasRunServerPath() const { return !_runServerPath.isEmpty(); }
|
||||
QString getRunServerPath() const { return _runServerPath; }
|
||||
|
||||
// virtual functions required for PluginContainer
|
||||
virtual ui::Menu* getPrimaryMenu() override;
|
||||
|
@ -127,7 +140,7 @@ public:
|
|||
static void initPlugins(const QStringList& arguments);
|
||||
static void shutdownPlugins();
|
||||
|
||||
Application(int& argc, char** argv, QElapsedTimer& startup_time);
|
||||
Application(int& argc, char** argv, QElapsedTimer& startup_time, bool runServer, QString runServerPathOption);
|
||||
~Application();
|
||||
|
||||
void postLambdaEvent(std::function<void()> f) override;
|
||||
|
|
|
@ -23,9 +23,10 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Menu.h"
|
||||
|
||||
static const QString RUNNING_MARKER_FILENAME = "Interface.running";
|
||||
#include <RunningMarker.h>
|
||||
|
||||
bool CrashHandler::checkForResetSettings(bool suppressPrompt) {
|
||||
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||
|
@ -39,7 +40,7 @@ bool CrashHandler::checkForResetSettings(bool suppressPrompt) {
|
|||
// If option does not exist in Interface.ini so assume default behavior.
|
||||
bool displaySettingsResetOnCrash = !displayCrashOptions.isValid() || displayCrashOptions.toBool();
|
||||
|
||||
QFile runningMarkerFile(runningMarkerFilePath());
|
||||
QFile runningMarkerFile(RunningMarker::getMarkerFilePath(RUNNING_MARKER_FILENAME));
|
||||
bool wasLikelyCrash = runningMarkerFile.exists();
|
||||
|
||||
if (suppressPrompt) {
|
||||
|
@ -161,20 +162,3 @@ void CrashHandler::handleCrash(CrashHandler::Action action) {
|
|||
}
|
||||
}
|
||||
|
||||
void CrashHandler::writeRunningMarkerFiler() {
|
||||
QFile runningMarkerFile(runningMarkerFilePath());
|
||||
if (!runningMarkerFile.exists()) {
|
||||
runningMarkerFile.open(QIODevice::WriteOnly);
|
||||
runningMarkerFile.close();
|
||||
}
|
||||
}
|
||||
void CrashHandler::deleteRunningMarkerFile() {
|
||||
QFile runningMarkerFile(runningMarkerFilePath());
|
||||
if (runningMarkerFile.exists()) {
|
||||
runningMarkerFile.remove();
|
||||
}
|
||||
}
|
||||
|
||||
const QString CrashHandler::runningMarkerFilePath() {
|
||||
return QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + RUNNING_MARKER_FILENAME;
|
||||
}
|
||||
|
|
|
@ -19,9 +19,6 @@ class CrashHandler {
|
|||
public:
|
||||
static bool checkForResetSettings(bool suppressPrompt = false);
|
||||
|
||||
static void writeRunningMarkerFiler();
|
||||
static void deleteRunningMarkerFile();
|
||||
|
||||
private:
|
||||
enum Action {
|
||||
DELETE_INTERFACE_INI,
|
||||
|
@ -31,8 +28,6 @@ private:
|
|||
|
||||
static Action promptUserForAction(bool showCrashMessage);
|
||||
static void handleCrash(Action action);
|
||||
|
||||
static const QString runningMarkerFilePath();
|
||||
};
|
||||
|
||||
#endif // hifi_CrashHandler_h
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include <CrashReporter.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
#if HAS_BUGSPLAT
|
||||
static QString BUG_SPLAT_DATABASE = "interface_alpha";
|
||||
|
@ -128,22 +130,9 @@ int main(int argc, const char* argv[]) {
|
|||
parser.addOption(runServerOption);
|
||||
parser.addOption(serverContentPathOption);
|
||||
parser.parse(arguments);
|
||||
if (parser.isSet(runServerOption)) {
|
||||
QString applicationDirPath = QFileInfo(arguments[0]).path();
|
||||
QString serverPath = applicationDirPath + "/server-console/server-console.exe";
|
||||
qDebug() << "Application dir path is: " << applicationDirPath;
|
||||
qDebug() << "Server path is: " << serverPath;
|
||||
QStringList args;
|
||||
if (parser.isSet(serverContentPathOption)) {
|
||||
QString serverContentPath = QFileInfo(arguments[0]).path() + "/" + parser.value(serverContentPathOption);
|
||||
args << "--" << "--contentPath" << serverContentPath;
|
||||
}
|
||||
qDebug() << QFileInfo(arguments[0]).path();
|
||||
qDebug() << QProcess::startDetached(serverPath, args);
|
||||
|
||||
// Sleep a short amount of time to give the server a chance to start
|
||||
usleep(2000000);
|
||||
}
|
||||
bool runServer = parser.isSet(runServerOption);
|
||||
bool serverContentPathOptionIsSet = parser.isSet(serverContentPathOption);
|
||||
QString serverContentPathOptionValue = serverContentPathOptionIsSet ? parser.value(serverContentPathOption) : QString();
|
||||
|
||||
QElapsedTimer startupTime;
|
||||
startupTime.start();
|
||||
|
@ -166,10 +155,11 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
SteamClient::init();
|
||||
|
||||
|
||||
int exitCode;
|
||||
{
|
||||
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||
Application app(argc, const_cast<char**>(argv), startupTime);
|
||||
Application app(argc, const_cast<char**>(argv), startupTime, runServer, serverContentPathOptionValue);
|
||||
|
||||
// If we failed the OpenGLVersion check, log it.
|
||||
if (override) {
|
||||
|
@ -223,7 +213,6 @@ int main(int argc, const char* argv[]) {
|
|||
QTranslator translator;
|
||||
translator.load("i18n/interface_en");
|
||||
app.installTranslator(&translator);
|
||||
|
||||
qCDebug(interfaceapp, "Created QT Application.");
|
||||
exitCode = app.exec();
|
||||
server.close();
|
||||
|
|
|
@ -831,32 +831,3 @@ void AddressManager::addCurrentAddressToHistory(LookupTrigger trigger) {
|
|||
}
|
||||
}
|
||||
|
||||
void AddressManager::ifLocalSandboxRunningElse(std::function<void()> localSandboxRunningDoThis,
|
||||
std::function<void()> localSandboxNotRunningDoThat) {
|
||||
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
QNetworkRequest sandboxStatus(SANDBOX_STATUS_URL);
|
||||
sandboxStatus.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
sandboxStatus.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||
QNetworkReply* reply = networkAccessManager.get(sandboxStatus);
|
||||
|
||||
connect(reply, &QNetworkReply::finished, this, [reply, localSandboxRunningDoThis, localSandboxNotRunningDoThat]() {
|
||||
auto statusData = reply->readAll();
|
||||
auto statusJson = QJsonDocument::fromJson(statusData);
|
||||
if (!statusJson.isEmpty()) {
|
||||
auto statusObject = statusJson.object();
|
||||
auto serversValue = statusObject.value("servers");
|
||||
if (!serversValue.isUndefined() && serversValue.isObject()) {
|
||||
auto serversObject = serversValue.toObject();
|
||||
auto serversCount = serversObject.size();
|
||||
const int MINIMUM_EXPECTED_SERVER_COUNT = 5;
|
||||
if (serversCount >= MINIMUM_EXPECTED_SERVER_COUNT) {
|
||||
localSandboxRunningDoThis();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
localSandboxNotRunningDoThat();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
const QString HIFI_URL_SCHEME = "hifi";
|
||||
const QString DEFAULT_HIFI_ADDRESS = "hifi://welcome";
|
||||
const QString SANDBOX_HIFI_ADDRESS = "hifi://localhost";
|
||||
const QString SANDBOX_STATUS_URL = "http://localhost:60332/status";
|
||||
const QString INDEX_PATH = "/";
|
||||
|
||||
const QString GET_PLACE = "/api/v1/places/%1";
|
||||
|
@ -78,11 +77,6 @@ public:
|
|||
const QStack<QUrl>& getBackStack() const { return _backStack; }
|
||||
const QStack<QUrl>& getForwardStack() const { return _forwardStack; }
|
||||
|
||||
/// determines if the local sandbox is likely running. It does not account for custom setups, and is only
|
||||
/// intended to detect the standard local sandbox install.
|
||||
void ifLocalSandboxRunningElse(std::function<void()> localSandboxRunningDoThis,
|
||||
std::function<void()> localSandboxNotRunningDoThat);
|
||||
|
||||
public slots:
|
||||
void handleLookupString(const QString& lookupString, bool fromSuggestions = false);
|
||||
|
||||
|
|
96
libraries/networking/src/SandboxUtils.cpp
Normal file
96
libraries/networking/src/SandboxUtils.cpp
Normal file
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// SandboxUtils.cpp
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2016-10-15.
|
||||
// Copyright 2016 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 <QDataStream>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkReply>
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
|
||||
#include <NumericalConstants.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <RunningMarker.h>
|
||||
|
||||
#include "SandboxUtils.h"
|
||||
#include "NetworkAccessManager.h"
|
||||
|
||||
|
||||
void SandboxUtils::ifLocalSandboxRunningElse(std::function<void()> localSandboxRunningDoThis,
|
||||
std::function<void()> localSandboxNotRunningDoThat) {
|
||||
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
QNetworkRequest sandboxStatus(SANDBOX_STATUS_URL);
|
||||
sandboxStatus.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
sandboxStatus.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
|
||||
QNetworkReply* reply = networkAccessManager.get(sandboxStatus);
|
||||
|
||||
connect(reply, &QNetworkReply::finished, this, [reply, localSandboxRunningDoThis, localSandboxNotRunningDoThat]() {
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
auto statusData = reply->readAll();
|
||||
auto statusJson = QJsonDocument::fromJson(statusData);
|
||||
if (!statusJson.isEmpty()) {
|
||||
auto statusObject = statusJson.object();
|
||||
auto serversValue = statusObject.value("servers");
|
||||
if (!serversValue.isUndefined() && serversValue.isObject()) {
|
||||
auto serversObject = serversValue.toObject();
|
||||
auto serversCount = serversObject.size();
|
||||
const int MINIMUM_EXPECTED_SERVER_COUNT = 5;
|
||||
if (serversCount >= MINIMUM_EXPECTED_SERVER_COUNT) {
|
||||
localSandboxRunningDoThis();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
localSandboxNotRunningDoThat();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void SandboxUtils::runLocalSandbox(QString contentPath, bool autoShutdown, QString runningMarkerName) {
|
||||
QString applicationDirPath = QFileInfo(QCoreApplication::applicationFilePath()).path();
|
||||
QString serverPath = applicationDirPath + "/server-console/server-console.exe";
|
||||
qDebug() << "Application dir path is: " << applicationDirPath;
|
||||
qDebug() << "Server path is: " << serverPath;
|
||||
qDebug() << "autoShutdown: " << autoShutdown;
|
||||
|
||||
bool hasContentPath = !contentPath.isEmpty();
|
||||
bool passArgs = autoShutdown || hasContentPath;
|
||||
|
||||
QStringList args;
|
||||
|
||||
if (passArgs) {
|
||||
args << "--";
|
||||
}
|
||||
|
||||
if (hasContentPath) {
|
||||
QString serverContentPath = applicationDirPath + "/" + contentPath;
|
||||
args << "--contentPath" << serverContentPath;
|
||||
}
|
||||
|
||||
if (autoShutdown) {
|
||||
QString interfaceRunningStateFile = RunningMarker::getMarkerFilePath(runningMarkerName);
|
||||
args << "--shutdownWatcher" << interfaceRunningStateFile;
|
||||
}
|
||||
|
||||
qDebug() << applicationDirPath;
|
||||
qDebug() << "Launching sandbox with:" << args;
|
||||
qDebug() << QProcess::startDetached(serverPath, args);
|
||||
|
||||
// Sleep a short amount of time to give the server a chance to start
|
||||
usleep(2000000); /// do we really need this??
|
||||
}
|
32
libraries/networking/src/SandboxUtils.h
Normal file
32
libraries/networking/src/SandboxUtils.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// SandboxUtils.h
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2016-10-15.
|
||||
// Copyright 2016 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
|
||||
//
|
||||
|
||||
#ifndef hifi_SandboxUtils_h
|
||||
#define hifi_SandboxUtils_h
|
||||
|
||||
#include <functional>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
|
||||
const QString SANDBOX_STATUS_URL = "http://localhost:60332/status";
|
||||
|
||||
class SandboxUtils : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/// determines if the local sandbox is likely running. It does not account for custom setups, and is only
|
||||
/// intended to detect the standard local sandbox install.
|
||||
void ifLocalSandboxRunningElse(std::function<void()> localSandboxRunningDoThis,
|
||||
std::function<void()> localSandboxNotRunningDoThat);
|
||||
|
||||
static void runLocalSandbox(QString contentPath, bool autoShutdown, QString runningMarkerName);
|
||||
};
|
||||
|
||||
#endif // hifi_SandboxUtils_h
|
73
libraries/shared/src/RunningMarker.cpp
Normal file
73
libraries/shared/src/RunningMarker.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// RunningMarker.cpp
|
||||
// libraries/shared/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2016-10-16
|
||||
// Copyright 2016 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 "RunningMarker.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QStandardPaths>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
|
||||
#include "NumericalConstants.h"
|
||||
#include "PathUtils.h"
|
||||
|
||||
|
||||
RunningMarker::RunningMarker(QObject* parent, QString name) :
|
||||
_parent(parent),
|
||||
_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
|
||||
QThread* runningMarkerThread = new QThread(_parent);
|
||||
runningMarkerThread->setObjectName("Running Marker Thread");
|
||||
runningMarkerThread->start();
|
||||
|
||||
writeRunningMarkerFiler(); // write the first file, even before timer
|
||||
|
||||
QTimer* runningMarkerTimer = new QTimer(_parent);
|
||||
QObject::connect(runningMarkerTimer, &QTimer::timeout, [=](){
|
||||
writeRunningMarkerFiler();
|
||||
});
|
||||
runningMarkerTimer->start(RUNNING_STATE_CHECK_IN_MSECS);
|
||||
}
|
||||
|
||||
RunningMarker::~RunningMarker() {
|
||||
deleteRunningMarkerFile();
|
||||
}
|
||||
|
||||
void RunningMarker::writeRunningMarkerFiler() {
|
||||
QFile runningMarkerFile(getFilePath());
|
||||
|
||||
// always write, even it it exists, so that it touches the files
|
||||
if (runningMarkerFile.open(QIODevice::WriteOnly)) {
|
||||
runningMarkerFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
void RunningMarker::deleteRunningMarkerFile() {
|
||||
QFile runningMarkerFile(getFilePath());
|
||||
if (runningMarkerFile.exists()) {
|
||||
runningMarkerFile.remove();
|
||||
}
|
||||
}
|
||||
|
||||
QString RunningMarker::getFilePath() {
|
||||
return QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + _name;
|
||||
}
|
||||
|
||||
QString RunningMarker::getMarkerFilePath(QString name) {
|
||||
return QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + name;
|
||||
}
|
||||
|
35
libraries/shared/src/RunningMarker.h
Normal file
35
libraries/shared/src/RunningMarker.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// RunningMarker.h
|
||||
// interface/src
|
||||
//
|
||||
// Created by David Rowe on 24 Aug 2015.
|
||||
// Copyright 2015 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
|
||||
//
|
||||
|
||||
#ifndef hifi_RunningMarker_h
|
||||
#define hifi_RunningMarker_h
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class RunningMarker {
|
||||
public:
|
||||
RunningMarker(QObject* parent, QString name);
|
||||
~RunningMarker();
|
||||
|
||||
void startRunningMarker();
|
||||
|
||||
QString getFilePath();
|
||||
static QString getMarkerFilePath(QString name);
|
||||
protected:
|
||||
void writeRunningMarkerFiler();
|
||||
void deleteRunningMarkerFile();
|
||||
|
||||
QObject* _parent { nullptr };
|
||||
QString _name;
|
||||
};
|
||||
|
||||
#endif // hifi_RunningMarker_h
|
|
@ -128,6 +128,12 @@ function shutdown() {
|
|||
}
|
||||
}
|
||||
|
||||
function forcedShutdown() {
|
||||
if (!isShuttingDown) {
|
||||
shutdownCallback(0);
|
||||
}
|
||||
}
|
||||
|
||||
function shutdownCallback(idx) {
|
||||
if (idx == 0 && !isShuttingDown) {
|
||||
isShuttingDown = true;
|
||||
|
@ -226,6 +232,7 @@ if (shouldQuit) {
|
|||
|
||||
// Check command line arguments to see how to find binaries
|
||||
var argv = require('yargs').argv;
|
||||
|
||||
var pathFinder = require('./modules/path-finder.js');
|
||||
|
||||
var interfacePath = null;
|
||||
|
@ -774,6 +781,7 @@ function maybeShowSplash() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
const trayIconOS = (osType == "Darwin") ? "osx" : "win";
|
||||
var trayIcons = {};
|
||||
trayIcons[ProcessGroupStates.STARTED] = "console-tray-" + trayIconOS + ".png";
|
||||
|
@ -842,6 +850,34 @@ function onContentLoaded() {
|
|||
// start the home server
|
||||
homeServer.start();
|
||||
}
|
||||
|
||||
// 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) {
|
||||
console.log("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) {
|
||||
console.log("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) {
|
||||
console.log("Running state of interface hasn't updated in MAX time... shutting down.");
|
||||
forcedShutdown();
|
||||
clearTimeout(shutdownWatchInterval);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue