feat: add a new core option --new-instance to skip the core check for a running instance

This commit is contained in:
sithlord48
2025-11-10 16:40:21 -05:00
committed by Chris Rizzitello
parent 5441464a1d
commit 859af720c9
4 changed files with 27 additions and 13 deletions

View File

@ -27,6 +27,8 @@ CoreArgParser::CoreArgParser(const QStringList &args)
m_helpText = m_parser.helpText().replace("<executable_name>", kCoreBinName);
m_helpText.replace("[options] coremode", "coremode [options]");
m_singleInstance = !m_parser.isSet(CoreArgs::multiInstanceOption);
}
void CoreArgParser::parse()
@ -95,3 +97,8 @@ bool CoreArgParser::clientMode() const
{
return m_clientMode;
}
bool CoreArgParser::singleInstanceOnly() const
{
return m_singleInstance;
}

View File

@ -33,6 +33,7 @@ public:
bool version() const;
bool serverMode() const;
bool clientMode() const;
bool singleInstanceOnly() const;
private:
[[noreturn]] void showHelpText() const;
@ -40,5 +41,6 @@ private:
QString m_helpText;
bool m_clientMode = false;
bool m_serverMode = false;
bool m_singleInstance = true;
static const QString s_headerText;
};

View File

@ -15,8 +15,10 @@ struct CoreArgs
{
inline static const auto helpOption = QCommandLineOption({"h", "help"}, "Display Help on the command line");
inline static const auto versionOption = QCommandLineOption({"v", "version"}, "Display version information");
inline static const auto multiInstanceOption =
QCommandLineOption("new-instance", "Skip the check for a running instance, always makes a new instance");
inline static const auto configOption =
QCommandLineOption({"s", "settings"}, "override configuration file to use", "configFile");
inline static const auto options = {helpOption, versionOption, configOption};
inline static const auto options = {helpOption, versionOption, multiInstanceOption, configOption};
};

View File

@ -11,6 +11,7 @@
#include "arch/Arch.h"
#include "base/EventQueue.h"
#include "base/Log.h"
#include "common/Constants.h"
#include "common/ExitCodes.h"
#include "deskflow/ClientApp.h"
#include "deskflow/ServerApp.h"
@ -65,20 +66,22 @@ int main(int argc, char **argv)
return s_exitSuccess;
}
// Before we check any more args we need to check for a duplicate process.
// Create a shared memory segment with a unique key
// This is to prevent a new instance from running if one is already running
QSharedMemory sharedMemory("deskflow-core");
if (parser.singleInstanceOnly()) {
// Before we check any more args we need to check for a duplicate process.
// Create a shared memory segment with a unique key
// This is to prevent a new instance from running if one is already running
QSharedMemory sharedMemory(kCoreBinName);
// Attempt to attach first and detach in order to clean up stale shm chunks
// This can happen if the previous instance was killed or crashed
if (sharedMemory.attach())
sharedMemory.detach();
// Attempt to attach first and detach in order to clean up stale shm chunks
// This can happen if the previous instance was killed or crashed
if (sharedMemory.attach())
sharedMemory.detach();
// If we can create 1 byte of SHM we are the only instance
if (!sharedMemory.create(1)) {
LOG_WARN("an instance of deskflow core is already running");
return s_exitDuplicate;
// If we can create 1 byte of SHM we are the only instance
if (!sharedMemory.create(1)) {
LOG_WARN("an instance of deskflow core is already running");
return s_exitDuplicate;
}
}
parser.parse();