[Pkg-running-devel] [openambit] 64/131: Added protection for simultaneous running instances (easiest way to share data-files and device is to not allow more than one instance!)

Christian Perrier bubulle at moszumanska.debian.org
Thu Jul 17 20:19:11 UTC 2014


This is an automated email from the git hooks/post-receive script.

bubulle pushed a commit to branch master
in repository openambit.

commit 679d82f9a3abe85d5d7a4c54ad745478d0e761ca
Author: Emil Ljungdahl <emil at kratern.se>
Date:   Wed Jan 22 21:50:35 2014 +0100

    Added protection for simultaneous running instances
    (easiest way to share data-files and device is to not allow more than one instance!)
---
 src/openambit/main.cpp               | 16 +++++++--
 src/openambit/mainwindow.cpp         | 14 ++++++++
 src/openambit/mainwindow.h           |  3 ++
 src/openambit/openambit.pro          |  6 ++--
 src/openambit/single_application.cpp | 68 ++++++++++++++++++++++++++++++++++++
 src/openambit/single_application.h   | 31 ++++++++++++++++
 6 files changed, 133 insertions(+), 5 deletions(-)

diff --git a/src/openambit/main.cpp b/src/openambit/main.cpp
index f8df990..8a4c207 100644
--- a/src/openambit/main.cpp
+++ b/src/openambit/main.cpp
@@ -20,13 +20,18 @@
  *
  */
 #include "mainwindow.h"
-#include <QApplication>
 #include <QSettings>
 
+#include "single_application.h"
+
 int main(int argc, char *argv[])
 {
-    QApplication a(argc, argv);
-    MainWindow w;
+    SingleApplication a(argc, argv, "openambit_single_application_lock");
+
+    if (a.isRunning()) {
+        a.sendMessage("focus");
+        return 0;
+    }
 
     // Set application settings
     QCoreApplication::setOrganizationName("openambit");
@@ -35,6 +40,11 @@ int main(int argc, char *argv[])
     QSettings::setPath(QSettings::NativeFormat, QSettings::UserScope, "~/.openambit/openambit.conf");
 #endif
 
+    MainWindow w;
+
+    // Connect single application message bus
+    QObject::connect(&a, SIGNAL(messageAvailable(QString)), &w, SLOT(singleApplicationMsgRecv(QString)));
+
     w.show();
     
     return a.exec();
diff --git a/src/openambit/mainwindow.cpp b/src/openambit/mainwindow.cpp
index 8fab96d..05eba3e 100644
--- a/src/openambit/mainwindow.cpp
+++ b/src/openambit/mainwindow.cpp
@@ -121,6 +121,20 @@ MainWindow::~MainWindow()
     delete ui;
 }
 
+void MainWindow::singleApplicationMsgRecv(QString msg)
+{
+    if (msg == "focus") {
+        // Another instance of application has asked use to gain focus, let's do so!
+        if (isMinimized()) {
+            showHideWindow();
+        }
+        else {
+            raise();
+            activateWindow();
+        }
+    }
+}
+
 void MainWindow::changeEvent(QEvent *event)
 {
     if (event->type() == QEvent::WindowStateChange) {
diff --git a/src/openambit/mainwindow.h b/src/openambit/mainwindow.h
index 29b591b..78b6e42 100644
--- a/src/openambit/mainwindow.h
+++ b/src/openambit/mainwindow.h
@@ -48,6 +48,9 @@ public:
 signals:
     void syncNow(bool readAll, bool syncTime, bool syncOrbit, bool syncMovescount);
 
+public slots:
+    void singleApplicationMsgRecv(QString msg);
+
 protected:
     void changeEvent(QEvent *event);
     void closeEvent(QCloseEvent *event);
diff --git a/src/openambit/openambit.pro b/src/openambit/openambit.pro
index 92eab30..03cc58b 100644
--- a/src/openambit/openambit.pro
+++ b/src/openambit/openambit.pro
@@ -24,7 +24,8 @@ SOURCES += main.cpp\
     movescount.cpp \
     udevlistener.cpp \
     confirmbetadialog.cpp \
-    movescountlogdirentry.cpp
+    movescountlogdirentry.cpp \
+    single_application.cpp
 
 HEADERS  += mainwindow.h \
     devicemanager.h \
@@ -37,7 +38,8 @@ HEADERS  += mainwindow.h \
     movescount.h \
     udevlistener.h \
     confirmbetadialog.h \
-    movescountlogdirentry.h
+    movescountlogdirentry.h \
+    single_application.h
 
 FORMS    += mainwindow.ui \
     settingsdialog.ui \
diff --git a/src/openambit/single_application.cpp b/src/openambit/single_application.cpp
new file mode 100644
index 0000000..61595b6
--- /dev/null
+++ b/src/openambit/single_application.cpp
@@ -0,0 +1,68 @@
+#include <QLocalSocket>
+
+#include "single_application.h"
+
+SingleApplication::SingleApplication(int &argc, char *argv[], const QString uniqueKey) : QApplication(argc, argv), _uniqueKey(uniqueKey)
+{
+    sharedMemory.setKey(_uniqueKey);
+    if (sharedMemory.attach())
+        _isRunning = true;
+    else
+    {
+        _isRunning = false;
+        // create shared memory.
+        if (!sharedMemory.create(1))
+        {
+            qDebug() << "Unable to create single instance.";
+            return;
+        }
+        // create local server and listen to incomming messages from other instances.
+        localServer = new QLocalServer(this);
+        connect(localServer, SIGNAL(newConnection()), this, SLOT(receiveMessage()));
+        localServer->listen(_uniqueKey);
+    }
+}
+
+// public slots.
+
+void SingleApplication::receiveMessage()
+{
+    QLocalSocket *localSocket = localServer->nextPendingConnection();
+    if (!localSocket->waitForReadyRead(timeout))
+    {
+        qDebug() << localSocket->errorString().toLatin1();
+        return;
+    }
+    QByteArray byteArray = localSocket->readAll();
+    QString message = QString::fromUtf8(byteArray.constData());
+    emit messageAvailable(message);
+    localSocket->disconnectFromServer();
+}
+
+// public functions.
+
+bool SingleApplication::isRunning()
+{
+    return _isRunning;
+}
+
+bool SingleApplication::sendMessage(const QString &message)
+{
+    if (!_isRunning)
+        return false;
+    QLocalSocket localSocket(this);
+    localSocket.connectToServer(_uniqueKey, QIODevice::WriteOnly);
+    if (!localSocket.waitForConnected(timeout))
+    {
+        qDebug() << localSocket.errorString().toLatin1();
+        return false;
+    }
+    localSocket.write(message.toUtf8());
+    if (!localSocket.waitForBytesWritten(timeout))
+    {
+        qDebug() << localSocket.errorString().toLatin1();
+        return false;
+    }
+    localSocket.disconnectFromServer();
+    return true;
+}
diff --git a/src/openambit/single_application.h b/src/openambit/single_application.h
new file mode 100644
index 0000000..fa66cc3
--- /dev/null
+++ b/src/openambit/single_application.h
@@ -0,0 +1,31 @@
+#ifndef SINGLE_APPLICATION_H
+#define SINGLE_APPLICATION_H
+
+#include <QApplication>
+#include <QSharedMemory>
+#include <QLocalServer>
+
+class SingleApplication : public QApplication
+{
+    Q_OBJECT
+public:
+    SingleApplication(int &argc, char *argv[], const QString uniqueKey);
+
+    bool isRunning();
+    bool sendMessage(const QString &message);
+
+public slots:
+    void receiveMessage();
+
+signals:
+    void messageAvailable(QString message);
+
+private:
+    bool _isRunning;
+    QString _uniqueKey;
+    QSharedMemory sharedMemory;
+    QLocalServer *localServer;
+
+    static const int timeout = 1000;
+};
+#endif // SINGLE_APPLICATION_H

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-running/openambit.git



More information about the Pkg-running-devel mailing list