refactor: Allocate daemon app and it's thread on stack to reduce memory leak risk
This commit is contained in:
@ -44,10 +44,8 @@ int main(int argc, char **argv)
|
||||
|
||||
LOG((CLOG_PRINT "%s daemon (v%s)", kAppName, kVersion));
|
||||
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
const auto pDaemon = &DaemonApp::instance();
|
||||
const auto initResult = pDaemon->init(&events, argc, argv);
|
||||
auto &daemon = DaemonApp::instance();
|
||||
const auto initResult = daemon.init(&events, argc, argv);
|
||||
|
||||
switch (initResult) {
|
||||
using enum DaemonApp::InitResult;
|
||||
@ -55,41 +53,45 @@ int main(int argc, char **argv)
|
||||
case StartDaemon: {
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
// Thread must be heap-allocated for deferred deletion on thread exit.
|
||||
// Avoid setting Qt ownership to prevent premature deletion (thread may run longer than Qt loop).
|
||||
auto *pDaemonThread = new QThread(); // NOSONAR - Qt memory
|
||||
pDaemon->moveToThread(pDaemonThread);
|
||||
QThread daemonThread;
|
||||
daemon.moveToThread(&daemonThread);
|
||||
|
||||
QObject::connect(pDaemonThread, &QThread::started, pDaemon, &DaemonApp::run);
|
||||
QObject::connect(pDaemonThread, &QThread::finished, pDaemon, &QObject::deleteLater);
|
||||
QObject::connect(pDaemonThread, &QThread::finished, pDaemonThread, &QThread::deleteLater);
|
||||
QObject::connect(pDaemonThread, &QThread::finished, QCoreApplication::instance(), &QCoreApplication::quit);
|
||||
QObject::connect(&daemonThread, &QThread::started, [&daemon, &daemonThread]() {
|
||||
daemon.run();
|
||||
daemonThread.quit();
|
||||
});
|
||||
QObject::connect(&daemonThread, &QThread::finished, &app, &QCoreApplication::quit);
|
||||
|
||||
// The daemon app is on it's own thread which doesn't have a Qt event loop, so we need to use direct connection.
|
||||
auto *ipcServer = new ipc::DaemonIpcServer(&app, QString::fromStdString(pDaemon->logFilename())); // NOSONAR
|
||||
ipc::DaemonIpcServer ipcServer(&app, QString::fromStdString(daemon.logFilename()));
|
||||
|
||||
// Use direct connection as the daemon app is on it's own thread, and so is on a different event loop.
|
||||
QObject::connect(
|
||||
ipcServer, &ipc::DaemonIpcServer::logLevelChanged, pDaemon, &DaemonApp::saveLogLevel, //
|
||||
&ipcServer, &ipc::DaemonIpcServer::logLevelChanged, &daemon, &DaemonApp::saveLogLevel, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
ipcServer, &ipc::DaemonIpcServer::elevateModeChanged, pDaemon, &DaemonApp::setElevate, //
|
||||
&ipcServer, &ipc::DaemonIpcServer::elevateModeChanged, &daemon, &DaemonApp::setElevate, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
ipcServer, &ipc::DaemonIpcServer::commandChanged, pDaemon, &DaemonApp::setCommand, //
|
||||
&ipcServer, &ipc::DaemonIpcServer::commandChanged, &daemon, &DaemonApp::setCommand, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
ipcServer, &ipc::DaemonIpcServer::startProcessRequested, pDaemon, &DaemonApp::applyWatchdogCommand, //
|
||||
&ipcServer, &ipc::DaemonIpcServer::startProcessRequested, &daemon, &DaemonApp::applyWatchdogCommand, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
ipcServer, &ipc::DaemonIpcServer::stopProcessRequested, pDaemon, &DaemonApp::clearWatchdogCommand, //
|
||||
&ipcServer, &ipc::DaemonIpcServer::stopProcessRequested, &daemon, &DaemonApp::clearWatchdogCommand, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
|
||||
pDaemonThread->start();
|
||||
return QCoreApplication::exec();
|
||||
daemonThread.start();
|
||||
const auto exitCode = QCoreApplication::exec();
|
||||
daemonThread.wait();
|
||||
|
||||
LOG_DEBUG("daemon exited, code: %d", exitCode);
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
case FatalError:
|
||||
|
||||
Reference in New Issue
Block a user