From 3ace62f90d48015fec1bd37ad216466fb666061d Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Fri, 22 Dec 2017 23:00:45 +0100 Subject: Single instance check works again - In Debug builds, startup time is calculated --- src/singleapplication.cpp | 87 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 20 deletions(-) (limited to 'src/singleapplication.cpp') diff --git a/src/singleapplication.cpp b/src/singleapplication.cpp index 1dd96e3..e71d1be 100644 --- a/src/singleapplication.cpp +++ b/src/singleapplication.cpp @@ -10,14 +10,47 @@ #include #include #include +#include +#include + +QHash paramStructToHash(const SingleApplication::SessionParam ¶ms) +{ + QHash hashedParams; + hashedParams.insert("profile", params.profile); + hashedParams.insert("newWindow", params.newWindow); + QList urls; + for(const QUrl &url : params.urls) { + urls.append(url); + } + hashedParams.insert("urls", urls); + return hashedParams; +} + +SingleApplication::SessionParam paramStructFromHash(const QHash ¶ms) +{ + SingleApplication::SessionParam structParams; + structParams.profile = params.value("profile").toString(); + structParams.newWindow = params.value("newWindow").toBool(); + for(const QVariant &val : params.value("urls").toList()) { + structParams.urls.append(val.toUrl()); + } + return structParams; +} SingleApplication::SingleApplication(int &argc, char **argv) : QApplication(argc, argv) { +#ifdef Q_OS_UNIX + // could be a path such as "/tmp/foo" + LOCALSERVER_KEY = "smolbote_socket"; +#elif Q_OS_WIN32 + // could be a pipe path such as "\\.\pipe\foo" + LOCALSERVER_KEY = "\\.\pipe\smolbote_socket"; +#endif } SingleApplication::~SingleApplication() { - if(m_localServer) { + if(m_localServer != nullptr) { if(m_localServer->isListening()) { m_localServer->close(); QLocalServer::removeServer(LOCALSERVER_KEY); @@ -25,56 +58,70 @@ SingleApplication::~SingleApplication() } } -void SingleApplication::bindLocalSocket() +/** + * @brief SingleApplication::bindLocalSocket check for running local server by connecting to it + * @return true if no other instance, false otherwise + */ +bool SingleApplication::bindLocalSocket(const QString &name) { - m_localServer = new QLocalServer(this); - connect(m_localServer, &QLocalServer::newConnection, this, &SingleApplication::slot_receiveMessage); + // if a name has been set + if(!name.isEmpty()) { + LOCALSERVER_KEY = name; + } - // check for running local server by connecting to it QLocalSocket socket; socket.connectToServer(LOCALSERVER_KEY); + if(socket.waitForConnected(LOCALSERVER_TIMEOUT)) { - // there is another server - qWarning("Another server is running"); + // another server is running socket.close(); - return; - } else { + return false; + } + + // there is either no such socket, or the socket wasn't cleaned up + else { + m_localServer = new QLocalServer(this); + connect(m_localServer, &QLocalServer::newConnection, this, &SingleApplication::parseMessage); + // no other server QLocalServer::removeServer(LOCALSERVER_KEY); if(!m_localServer->listen(LOCALSERVER_KEY)) { - qWarning("Cannot bind local server [%s]", qUtf8Printable(LOCALSERVER_KEY)); + // for some reason, we still can't bind the socket + return false; } + return true; } } -bool SingleApplication::isRunning() +QString SingleApplication::serverName() const { - return !m_localServer->isListening(); + Q_CHECK_PTR(m_localServer); + return m_localServer->fullServerName(); } -bool SingleApplication::sendMessage(const QHash ¶ms) +int SingleApplication::sendMessage(const SessionParam ¶ms) { QLocalSocket socket; socket.connectToServer(LOCALSERVER_KEY); if(socket.waitForConnected(LOCALSERVER_TIMEOUT)) { QByteArray argumentData; QDataStream ds(&argumentData, QIODevice::WriteOnly); - ds << params; + ds << paramStructToHash(params); socket.write(argumentData); socket.waitForBytesWritten(LOCALSERVER_TIMEOUT); - return true; + return EXIT_SUCCESS; } - return false; + return EXIT_FAILURE; } -void SingleApplication::slot_receiveMessage() +void SingleApplication::parseMessage() { QLocalSocket *socket = m_localServer->nextPendingConnection(); - if(!socket) { - // null socket --> return + // null socket --> return + if(socket == nullptr) { return; } @@ -93,5 +140,5 @@ void SingleApplication::slot_receiveMessage() socket->deleteLater(); - emit messageAvailable(params); + emit messageAvailable(paramStructFromHash(params)); } -- cgit v1.2.1