Skip to content

Commit 2af391f

Browse files
committed
feat: avoid duplicate ll-package-manager startup by checking existing
connection 1. Add `startProcess` helper to launch detached processes with proper environment and cleanup on exit. 2. Replace unconditional `startDetached` and sleep with a D-Bus peer connection check to see if `ll-package-manager` is already running. 3. Only start a new process when no existing daemon is detected; otherwise log reuse of existing instance. 4. Include signal handling to terminate spawned processes when the application quits. Log: Improved process management for ll-package-manager to prevent duplicate instances. Influence: 1. Verify that ll-package-manager starts correctly when not already running. 2. Test that when ll-package-manager is already running, a new process is not spawned. 3. Confirm that spawned processes are terminated when the main application exits. 4. Check logging output for "reuse existing process" or "start" messages. 5. Verify D-Bus connection to the peer socket works as expected. 6. Test in scenarios where the socket file might be stale or missing.
1 parent e2a26de commit 2af391f

1 file changed

Lines changed: 40 additions & 10 deletions

File tree

apps/ll-cli/src/main.cpp

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <CLI/CLI.hpp>
2424
#include <sys/file.h>
2525

26+
#include <QDBusConnection>
2627
#include <QDBusMetaType>
2728
#include <QDBusObjectPath>
2829
#include <QJsonDocument>
@@ -38,6 +39,7 @@
3839
#include <thread>
3940

4041
#include <fcntl.h>
42+
#include <signal.h>
4143
#include <unistd.h>
4244
#include <wordexp.h>
4345

@@ -47,6 +49,26 @@ using namespace linglong::cli;
4749

4850
namespace {
4951

52+
void startProcess(const QString &program, const QStringList &args = {})
53+
{
54+
QProcess process;
55+
auto envs = process.environment();
56+
envs.push_back("QT_FORCE_STDERR_LOGGING=1");
57+
process.setEnvironment(envs);
58+
process.setProgram(program);
59+
process.setArguments(args);
60+
61+
qint64 pid = 0;
62+
process.startDetached(&pid);
63+
64+
LogD("start {} {} as {}", program.toStdString(), args.join(" ").toStdString(), pid);
65+
66+
QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, [pid]() {
67+
LogD("kill {}", pid);
68+
kill(pid, SIGTERM);
69+
});
70+
}
71+
5072
std::vector<std::string> transformOldExec(int argc, char **argv) noexcept
5173
{
5274
std::vector<std::string> res;
@@ -692,16 +714,24 @@ You can report bugs to the linyaps team under this project: https://github.com/O
692714
return -1;
693715
}
694716

695-
// Start ll-package-manager --no-dbus first to initialize the repository
696-
QProcess::startDetached("sudo",
697-
{ "--user",
698-
LINGLONG_USERNAME,
699-
"--preserve-env=QT_FORCE_STDERR_LOGGING",
700-
"--preserve-env=QDBUS_DEBUG",
701-
LINGLONG_LIBEXEC_DIR "/ll-package-manager",
702-
"--no-dbus" });
703-
using namespace std::chrono_literals;
704-
std::this_thread::sleep_for(1s);
717+
const auto pkgManAddress = QString("unix:path=/tmp/linglong-package-manager.socket");
718+
719+
// Check if ll-package-manager is already running
720+
auto pkgManConn = QDBusConnection::connectToPeer(pkgManAddress, "ll-package-manager");
721+
if (!pkgManConn.isConnected()) {
722+
// Only start a new process if no existing one is listening
723+
startProcess("sudo",
724+
{ "--user",
725+
LINGLONG_USERNAME,
726+
"--preserve-env=QT_FORCE_STDERR_LOGGING",
727+
"--preserve-env=QDBUS_DEBUG",
728+
LINGLONG_LIBEXEC_DIR "/ll-package-manager",
729+
"--no-dbus" });
730+
using namespace std::chrono_literals;
731+
std::this_thread::sleep_for(1s);
732+
} else {
733+
LogD("ll-package-manager is already running, reuse existing process");
734+
}
705735
}
706736
auto repo = linglong::repo::OSTreeRepo::loadFromPath(LINGLONG_ROOT);
707737
if (!repo.has_value()) {

0 commit comments

Comments
 (0)