mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
* Print stack trace on crash * Printing stack trace is fully functional except for WIN32 * Minor fixes * Minor fixes
This commit is contained in:
parent
9c5e5cac24
commit
3b48d8c9d6
@ -16,6 +16,7 @@ public:
|
|||||||
VideoStandard videoStandard,
|
VideoStandard videoStandard,
|
||||||
PixelFormat pixelFormat,
|
PixelFormat pixelFormat,
|
||||||
int pixelDecimation );
|
int pixelDecimation );
|
||||||
|
~V4L2Wrapper() override;
|
||||||
|
|
||||||
bool getSignalDetectionEnable();
|
bool getSignalDetectionEnable();
|
||||||
|
|
||||||
|
@ -26,6 +26,11 @@ public:
|
|||||||
///
|
///
|
||||||
X11Wrapper(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, const unsigned updateRate_Hz);
|
X11Wrapper(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, const unsigned updateRate_Hz);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Destructor of this framebuffer frame grabber. Releases any claimed resources.
|
||||||
|
///
|
||||||
|
~X11Wrapper() override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
///
|
///
|
||||||
/// Performs a single frame grab and computes the led-colors
|
/// Performs a single frame grab and computes the led-colors
|
||||||
|
6
include/utils/DefaultSignalHandler.h
Normal file
6
include/utils/DefaultSignalHandler.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace DefaultSignalHandler
|
||||||
|
{
|
||||||
|
void install();
|
||||||
|
}
|
@ -4,7 +4,7 @@ DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHe
|
|||||||
: GrabberWrapper("Dispmanx", &_grabber, grabWidth, grabHeight, updateRate_Hz)
|
: GrabberWrapper("Dispmanx", &_grabber, grabWidth, grabHeight, updateRate_Hz)
|
||||||
, _grabber(grabWidth, grabHeight)
|
, _grabber(grabWidth, grabHeight)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispmanxWrapper::action()
|
void DispmanxWrapper::action()
|
||||||
|
@ -33,6 +33,11 @@ V4L2Wrapper::V4L2Wrapper(const QString &device,
|
|||||||
connect(&_grabber, SIGNAL(readError(const char*)), this, SLOT(readError(const char*)), Qt::DirectConnection);
|
connect(&_grabber, SIGNAL(readError(const char*)), this, SLOT(readError(const char*)), Qt::DirectConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
V4L2Wrapper::~V4L2Wrapper()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
bool V4L2Wrapper::start()
|
bool V4L2Wrapper::start()
|
||||||
{
|
{
|
||||||
return ( _grabber.start() && GrabberWrapper::start());
|
return ( _grabber.start() && GrabberWrapper::start());
|
||||||
|
@ -6,6 +6,14 @@ X11Wrapper::X11Wrapper(int cropLeft, int cropRight, int cropTop, int cropBottom,
|
|||||||
, _init(false)
|
, _init(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
X11Wrapper::~X11Wrapper()
|
||||||
|
{
|
||||||
|
if ( _init )
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void X11Wrapper::action()
|
void X11Wrapper::action()
|
||||||
{
|
{
|
||||||
if (! _init )
|
if (! _init )
|
||||||
|
@ -39,7 +39,7 @@ GrabberWrapper::GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned
|
|||||||
|
|
||||||
GrabberWrapper::~GrabberWrapper()
|
GrabberWrapper::~GrabberWrapper()
|
||||||
{
|
{
|
||||||
GrabberWrapper::stop(); // TODO Is this right????????
|
stop();
|
||||||
Debug(_log,"Close grabber: %s", QSTRING_CSTR(_grabberName));
|
Debug(_log,"Close grabber: %s", QSTRING_CSTR(_grabberName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,9 +53,12 @@ bool GrabberWrapper::start()
|
|||||||
|
|
||||||
void GrabberWrapper::stop()
|
void GrabberWrapper::stop()
|
||||||
{
|
{
|
||||||
// Stop the timer, effectivly stopping the process
|
if (_timer->isActive())
|
||||||
Debug(_log,"Grabber stop()");
|
{
|
||||||
_timer->stop();
|
// Stop the timer, effectivly stopping the process
|
||||||
|
Debug(_log,"Grabber stop()");
|
||||||
|
_timer->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList GrabberWrapper::availableGrabbers()
|
QStringList GrabberWrapper::availableGrabbers()
|
||||||
@ -216,7 +219,7 @@ void GrabberWrapper::handleSourceRequest(const hyperion::Components& component,
|
|||||||
|
|
||||||
void GrabberWrapper::tryStart()
|
void GrabberWrapper::tryStart()
|
||||||
{
|
{
|
||||||
// verify start condition
|
// verify start condition
|
||||||
if((_grabberName.startsWith("V4L") && !GRABBER_V4L_CLIENTS.empty()) || (!_grabberName.startsWith("V4L") && !GRABBER_SYS_CLIENTS.empty()))
|
if((_grabberName.startsWith("V4L") && !GRABBER_V4L_CLIENTS.empty()) || (!_grabberName.startsWith("V4L") && !GRABBER_SYS_CLIENTS.empty()))
|
||||||
{
|
{
|
||||||
start();
|
start();
|
||||||
|
@ -141,9 +141,8 @@ void Hyperion::start()
|
|||||||
_boblightServer = new BoblightServer(this, getSetting(settings::BOBLSERVER));
|
_boblightServer = new BoblightServer(this, getSetting(settings::BOBLSERVER));
|
||||||
connect(this, &Hyperion::settingsChanged, _boblightServer, &BoblightServer::handleSettingsUpdate);
|
connect(this, &Hyperion::settingsChanged, _boblightServer, &BoblightServer::handleSettingsUpdate);
|
||||||
|
|
||||||
// instance inited
|
// instance inited, enter thread event loop
|
||||||
emit started();
|
emit started();
|
||||||
// enter thread event loop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hyperion::stop()
|
void Hyperion::stop()
|
||||||
@ -380,18 +379,8 @@ void Hyperion::setColor(const int priority, const std::vector<ColorRgb> &ledColo
|
|||||||
_effectEngine->channelCleared(priority);
|
_effectEngine->channelCleared(priority);
|
||||||
|
|
||||||
// create full led vector from single/multiple colors
|
// create full led vector from single/multiple colors
|
||||||
size_t size = _ledString.leds().size();
|
|
||||||
std::vector<ColorRgb> newLedColors;
|
std::vector<ColorRgb> newLedColors;
|
||||||
while (true)
|
std::copy_n(ledColors.begin(), _ledString.leds().size(), std::back_inserter(newLedColors));
|
||||||
{
|
|
||||||
for (const auto &entry : ledColors)
|
|
||||||
{
|
|
||||||
newLedColors.emplace_back(entry);
|
|
||||||
if (newLedColors.size() == size)
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end:
|
|
||||||
|
|
||||||
if (getPriorityInfo(priority).componentId != hyperion::COMP_COLOR)
|
if (getPriorityInfo(priority).componentId != hyperion::COMP_COLOR)
|
||||||
clear(priority);
|
clear(priority);
|
||||||
|
@ -36,7 +36,7 @@ LedDevice::LedDevice(const QJsonObject& config, QObject* parent)
|
|||||||
|
|
||||||
LedDevice::~LedDevice()
|
LedDevice::~LedDevice()
|
||||||
{
|
{
|
||||||
_refresh_timer->deleteLater();
|
delete _refresh_timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDevice::open()
|
int LedDevice::open()
|
||||||
|
@ -39,7 +39,7 @@ bool ProviderSpi::init(const QJsonObject &deviceConfig)
|
|||||||
_baudRate_Hz = deviceConfig["rate"].toInt(_baudRate_Hz);
|
_baudRate_Hz = deviceConfig["rate"].toInt(_baudRate_Hz);
|
||||||
_spiMode = deviceConfig["spimode"].toInt(_spiMode);
|
_spiMode = deviceConfig["spimode"].toInt(_spiMode);
|
||||||
_spiDataInvert = deviceConfig["invert"].toBool(_spiDataInvert);
|
_spiDataInvert = deviceConfig["invert"].toBool(_spiDataInvert);
|
||||||
|
|
||||||
return isInitOK;
|
return isInitOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,20 +116,17 @@ void SSDPHandler::handleWebServerStateChange(const bool newState)
|
|||||||
void SSDPHandler::handleNetworkConfigurationChanged(const QNetworkConfiguration &config)
|
void SSDPHandler::handleNetworkConfigurationChanged(const QNetworkConfiguration &config)
|
||||||
{
|
{
|
||||||
// get localAddress from interface
|
// get localAddress from interface
|
||||||
if(!getLocalAddress().isEmpty())
|
QString localAddress = getLocalAddress();
|
||||||
|
if(!localAddress.isEmpty() && _localAddress != localAddress)
|
||||||
{
|
{
|
||||||
QString localAddress = getLocalAddress();
|
// revoke old ip
|
||||||
if(_localAddress != localAddress)
|
sendAnnounceList(false);
|
||||||
{
|
|
||||||
// revoke old ip
|
|
||||||
sendAnnounceList(false);
|
|
||||||
|
|
||||||
// update desc & notify new ip
|
// update desc & notify new ip
|
||||||
_localAddress = localAddress;
|
_localAddress = localAddress;
|
||||||
_webserver->setSSDPDescription(buildDesc());
|
_webserver->setSSDPDescription(buildDesc());
|
||||||
setDescriptionAddress(getDescAddress());
|
setDescriptionAddress(getDescAddress());
|
||||||
sendAnnounceList(true);
|
sendAnnounceList(true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
132
libsrc/utils/DefaultSignalHandler.cpp
Normal file
132
libsrc/utils/DefaultSignalHandler.cpp
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#ifndef _WIN32
|
||||||
|
|
||||||
|
#include <utils/DefaultSignalHandler.h>
|
||||||
|
#include <utils/Logger.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
namespace DefaultSignalHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string decipher_trace(const std::string &trace)
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
if(trace.empty())
|
||||||
|
{
|
||||||
|
result += "??\n";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* begin = strchr(trace.c_str(), '(') + 1;
|
||||||
|
auto* end = strchr(begin, '+');
|
||||||
|
|
||||||
|
if(!end)
|
||||||
|
end = strchr(begin, ')');
|
||||||
|
|
||||||
|
std::string mangled_name(begin, end);
|
||||||
|
|
||||||
|
int status;
|
||||||
|
char * realname = abi::__cxa_demangle(mangled_name.c_str(), 0, 0, &status);
|
||||||
|
result.insert(result.end(), trace.c_str(), begin);
|
||||||
|
|
||||||
|
if(realname)
|
||||||
|
result += realname;
|
||||||
|
else
|
||||||
|
result.insert(result.end(), begin, end);
|
||||||
|
|
||||||
|
free(realname);
|
||||||
|
result.insert(result.size(), end);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_trace()
|
||||||
|
{
|
||||||
|
const int MAX_SIZE = 50;
|
||||||
|
void * addresses[MAX_SIZE];
|
||||||
|
int size = backtrace(addresses, MAX_SIZE);
|
||||||
|
|
||||||
|
if (!size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Logger* log = Logger::getInstance("CORE");
|
||||||
|
char ** symbols = backtrace_symbols(addresses, size);
|
||||||
|
for (int i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
std::string line = "\t" + decipher_trace(symbols[i]);
|
||||||
|
Error(log, line.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
free(symbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note that this signal handler is not async signal safe !
|
||||||
|
* Ideally a signal handler should only flip a bit and defer
|
||||||
|
* heavy work to some kind of bottom-half processing. */
|
||||||
|
void signal_handler(int signum, siginfo_t * /*info*/, void * /*context*/)
|
||||||
|
{
|
||||||
|
Logger* log = Logger::getInstance("SIGNAL");
|
||||||
|
|
||||||
|
char *name = strsignal(signum);
|
||||||
|
if (name)
|
||||||
|
{
|
||||||
|
Info(log, "Signal received : %s", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(signum)
|
||||||
|
{
|
||||||
|
case SIGSEGV:
|
||||||
|
case SIGABRT:
|
||||||
|
case SIGFPE :
|
||||||
|
print_trace();
|
||||||
|
exit(1);
|
||||||
|
case SIGINT :
|
||||||
|
case SIGTERM:
|
||||||
|
case SIGPIPE:
|
||||||
|
default:
|
||||||
|
/* If the signal_handler is hit before the event loop is started,
|
||||||
|
* following call will do nothing. So we queue the call. */
|
||||||
|
|
||||||
|
// QCoreApplication::quit();
|
||||||
|
QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
|
||||||
|
|
||||||
|
// Reset signal handler to default (in case this handler is not capable of stopping)
|
||||||
|
struct sigaction action{};
|
||||||
|
action.sa_handler = SIG_DFL;
|
||||||
|
sigaction(signum, &action, nullptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace DefaultSignalHandler
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
namespace DefaultSignalHandler
|
||||||
|
{
|
||||||
|
void install()
|
||||||
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
|
struct sigaction action{};
|
||||||
|
action.sa_sigaction = signal_handler;
|
||||||
|
action.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||||
|
|
||||||
|
sigaction(SIGHUP , &action, nullptr);
|
||||||
|
sigaction(SIGFPE , &action, nullptr);
|
||||||
|
sigaction(SIGINT , &action, nullptr);
|
||||||
|
sigaction(SIGTERM, &action, nullptr);
|
||||||
|
sigaction(SIGABRT, &action, nullptr);
|
||||||
|
sigaction(SIGSEGV, &action, nullptr);
|
||||||
|
sigaction(SIGPIPE, &action, nullptr);
|
||||||
|
#endif // _WIN32
|
||||||
|
}
|
||||||
|
} // namespace DefaultSignalHandler
|
@ -12,6 +12,8 @@
|
|||||||
// ssdp discover
|
// ssdp discover
|
||||||
#include <ssdp/SSDPDiscover.h>
|
#include <ssdp/SSDPDiscover.h>
|
||||||
|
|
||||||
|
#include <utils/DefaultSignalHandler.h>
|
||||||
|
|
||||||
using namespace commandline;
|
using namespace commandline;
|
||||||
|
|
||||||
// save the image as screenshot
|
// save the image as screenshot
|
||||||
@ -29,6 +31,8 @@ int main(int argc, char ** argv)
|
|||||||
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
|
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
|
||||||
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
||||||
|
|
||||||
|
DefaultSignalHandler::install();
|
||||||
|
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
// ssdp discover
|
// ssdp discover
|
||||||
#include <ssdp/SSDPDiscover.h>
|
#include <ssdp/SSDPDiscover.h>
|
||||||
|
|
||||||
|
#include <utils/DefaultSignalHandler.h>
|
||||||
|
|
||||||
using namespace commandline;
|
using namespace commandline;
|
||||||
|
|
||||||
// save the image as screenshot
|
// save the image as screenshot
|
||||||
@ -29,6 +31,8 @@ int main(int argc, char ** argv)
|
|||||||
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
|
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
|
||||||
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
||||||
|
|
||||||
|
DefaultSignalHandler::install();
|
||||||
|
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
// ssdp discover
|
// ssdp discover
|
||||||
#include <ssdp/SSDPDiscover.h>
|
#include <ssdp/SSDPDiscover.h>
|
||||||
|
|
||||||
|
#include <utils/DefaultSignalHandler.h>
|
||||||
|
|
||||||
using namespace commandline;
|
using namespace commandline;
|
||||||
|
|
||||||
// save the image as screenshot
|
// save the image as screenshot
|
||||||
@ -21,6 +23,8 @@ void saveScreenshot(QString filename, const Image<ColorRgb> & image)
|
|||||||
|
|
||||||
int main(int argc, char ** argv)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
|
DefaultSignalHandler::install();
|
||||||
|
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
// ssdp discover
|
// ssdp discover
|
||||||
#include <ssdp/SSDPDiscover.h>
|
#include <ssdp/SSDPDiscover.h>
|
||||||
|
|
||||||
|
#include <utils/DefaultSignalHandler.h>
|
||||||
|
|
||||||
using namespace commandline;
|
using namespace commandline;
|
||||||
|
|
||||||
// save the image as screenshot
|
// save the image as screenshot
|
||||||
@ -23,6 +25,8 @@ void saveScreenshot(QString filename, const Image<ColorRgb> & image)
|
|||||||
|
|
||||||
int main(int argc, char ** argv)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
|
DefaultSignalHandler::install();
|
||||||
|
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "HyperionConfig.h"
|
#include "HyperionConfig.h"
|
||||||
#include <commandline/Parser.h>
|
#include <commandline/Parser.h>
|
||||||
|
#include <utils/DefaultSignalHandler.h>
|
||||||
|
|
||||||
using namespace commandline;
|
using namespace commandline;
|
||||||
|
|
||||||
@ -66,6 +67,8 @@ int main(int argc, char * argv[])
|
|||||||
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
|
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
|
||||||
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
||||||
|
|
||||||
|
DefaultSignalHandler::install();
|
||||||
|
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
// force the locale
|
// force the locale
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
// ssdp discover
|
// ssdp discover
|
||||||
#include <ssdp/SSDPDiscover.h>
|
#include <ssdp/SSDPDiscover.h>
|
||||||
|
|
||||||
|
#include <utils/DefaultSignalHandler.h>
|
||||||
|
|
||||||
using namespace commandline;
|
using namespace commandline;
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <commandline/Parser.h>
|
#include <commandline/Parser.h>
|
||||||
#include <flatbufserver/FlatBufferConnection.h>
|
#include <flatbufserver/FlatBufferConnection.h>
|
||||||
|
#include <utils/DefaultSignalHandler.h>
|
||||||
#include "X11Wrapper.h"
|
#include "X11Wrapper.h"
|
||||||
#include "HyperionConfig.h"
|
#include "HyperionConfig.h"
|
||||||
|
|
||||||
@ -28,6 +29,8 @@ int main(int argc, char ** argv)
|
|||||||
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
|
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
|
||||||
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
||||||
|
|
||||||
|
DefaultSignalHandler::install();
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -11,54 +11,42 @@
|
|||||||
// psapi.h requires windows.h to be included
|
// psapi.h requires windows.h to be included
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <Psapi.h>
|
#include <Psapi.h>
|
||||||
|
#include <tlhelp32.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int getProcessIdsByProcessName(const char *processName, QStringList &listOfPids)
|
QStringList getProcessIdsByProcessName(const char *processName)
|
||||||
{
|
{
|
||||||
// Clear content of returned list of PIDS
|
QStringList listOfPids;
|
||||||
listOfPids.clear();
|
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
// Get the list of process identifiers.
|
// https://docs.microsoft.com/en-us/windows/win32/toolhelp/taking-a-snapshot-and-viewing-processes
|
||||||
DWORD aProcesses[1024], cbNeeded, cProcesses;
|
/* Take a snapshot of all processes in the system */
|
||||||
unsigned int i;
|
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
if(hProcessSnap == INVALID_HANDLE_VALUE)
|
||||||
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Calculate how many process identifiers were returned.
|
|
||||||
cProcesses = cbNeeded / sizeof(DWORD);
|
|
||||||
|
|
||||||
// Search for a matching name for each process
|
|
||||||
for (i = 0; i < cProcesses; i++)
|
|
||||||
{
|
{
|
||||||
if (aProcesses[i] != 0)
|
return {};
|
||||||
{
|
|
||||||
char szProcessName[MAX_PATH] = {0};
|
|
||||||
|
|
||||||
DWORD processID = aProcesses[i];
|
|
||||||
|
|
||||||
// Get a handle to the process.
|
|
||||||
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
|
|
||||||
|
|
||||||
// Get the process name
|
|
||||||
if (NULL != hProcess)
|
|
||||||
{
|
|
||||||
HMODULE hMod;
|
|
||||||
DWORD cbNeeded;
|
|
||||||
|
|
||||||
if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
|
|
||||||
GetModuleBaseNameA(hProcess, hMod, szProcessName, sizeof(szProcessName) / sizeof(char));
|
|
||||||
|
|
||||||
// Release the handle to the process.
|
|
||||||
CloseHandle(hProcess);
|
|
||||||
|
|
||||||
if (*szProcessName != 0 && strcmp(processName, szProcessName) == 0)
|
|
||||||
listOfPids.append(QString::number(processID));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROCESSENTRY32 pe32{};
|
||||||
|
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
|
||||||
|
/* Retrieve information about the first process */
|
||||||
|
if(!Process32First(hProcessSnap, &pe32))
|
||||||
|
{
|
||||||
|
CloseHandle(hProcessSnap);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk through the snapshot of processes */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (strcmp(processName, pe32.szExeFile) == 0)
|
||||||
|
listOfPids.append(QString::number(pe32.th32ProcessID));
|
||||||
|
|
||||||
|
} while(Process32Next(hProcessSnap, &pe32));
|
||||||
|
|
||||||
|
CloseHandle(hProcessSnap);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
QDir dir("/proc");
|
QDir dir("/proc");
|
||||||
@ -90,5 +78,5 @@ unsigned int getProcessIdsByProcessName(const char *processName, QStringList &li
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return listOfPids.count();
|
return listOfPids;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <utils/FileUtils.h>
|
#include <utils/FileUtils.h>
|
||||||
#include <commandline/Parser.h>
|
#include <commandline/Parser.h>
|
||||||
#include <commandline/IntOption.h>
|
#include <commandline/IntOption.h>
|
||||||
|
#include <utils/DefaultSignalHandler.h>
|
||||||
#include <../../include/db/AuthTable.h>
|
#include <../../include/db/AuthTable.h>
|
||||||
|
|
||||||
#include "detectProcess.h"
|
#include "detectProcess.h"
|
||||||
@ -76,11 +77,6 @@ void signal_handler(const int signum)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QCoreApplication::quit();
|
|
||||||
|
|
||||||
// reset signal handler to default (in case this handler is not capable of stopping)
|
|
||||||
signal(signum, SIG_DFL);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -150,14 +146,13 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
// check if we are running already an instance
|
// check if we are running already an instance
|
||||||
// TODO Allow one session per user
|
// TODO Allow one session per user
|
||||||
// http://www.qtcentre.org/threads/44489-Get-Process-ID-for-a-running-application
|
|
||||||
QStringList listOfPids;
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
const char* processName = "hyperiond.exe";
|
const char* processName = "hyperiond.exe";
|
||||||
#else
|
#else
|
||||||
const char* processName = "hyperiond";
|
const char* processName = "hyperiond";
|
||||||
#endif
|
#endif
|
||||||
if (getProcessIdsByProcessName(processName, listOfPids) > 1)
|
const QStringList listOfPids = getProcessIdsByProcessName(processName);
|
||||||
|
if (listOfPids.size() > 1)
|
||||||
{
|
{
|
||||||
Error(log, "The Hyperion Daemon is already running, abort start");
|
Error(log, "The Hyperion Daemon is already running, abort start");
|
||||||
return 0;
|
return 0;
|
||||||
@ -168,12 +163,10 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
bool isGuiApp = (qobject_cast<QApplication *>(app.data()) != 0 && QSystemTrayIcon::isSystemTrayAvailable());
|
bool isGuiApp = (qobject_cast<QApplication *>(app.data()) != 0 && QSystemTrayIcon::isSystemTrayAvailable());
|
||||||
|
|
||||||
|
DefaultSignalHandler::install();
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
signal(SIGINT, signal_handler);
|
|
||||||
signal(SIGTERM, signal_handler);
|
|
||||||
signal(SIGABRT, signal_handler);
|
|
||||||
signal(SIGCHLD, signal_handler);
|
signal(SIGCHLD, signal_handler);
|
||||||
signal(SIGPIPE, signal_handler);
|
|
||||||
signal(SIGUSR1, signal_handler);
|
signal(SIGUSR1, signal_handler);
|
||||||
signal(SIGUSR2, signal_handler);
|
signal(SIGUSR2, signal_handler);
|
||||||
#endif
|
#endif
|
||||||
@ -309,7 +302,7 @@ int main(int argc, char** argv)
|
|||||||
// delete database before start
|
// delete database before start
|
||||||
if(parser.isSet(deleteDB))
|
if(parser.isSet(deleteDB))
|
||||||
{
|
{
|
||||||
QString dbFile = mDir.absolutePath() + "/db/hyperion.db";
|
const QString dbFile = mDir.absolutePath() + "/db/hyperion.db";
|
||||||
if (QFile::exists(dbFile))
|
if (QFile::exists(dbFile))
|
||||||
{
|
{
|
||||||
if (!QFile::remove(dbFile))
|
if (!QFile::remove(dbFile))
|
||||||
|
@ -127,7 +127,7 @@ void SysTray::closeEvent(QCloseEvent *event)
|
|||||||
|
|
||||||
void SysTray::settings()
|
void SysTray::settings()
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
// Hide error messages when opening webbrowser
|
// Hide error messages when opening webbrowser
|
||||||
|
|
||||||
int out_pipe[2];
|
int out_pipe[2];
|
||||||
|
Loading…
Reference in New Issue
Block a user