1 files changed, 84 insertions, 0 deletions
diff --git a/src/RunGuard.cc b/src/RunGuard.cc
new file mode 100644
index 00000000..75833eb7
--- /dev/null
+++ b/src/RunGuard.cc
@@ -0,0 +1,84 @@
+#include "RunGuard.h"
+
+#include <QCryptographicHash>
+
+namespace {
+
+QString
+generateKeyHash(const QString &key, const QString &salt)
+{
+ QByteArray data;
+
+ data.append(key.toUtf8());
+ data.append(salt.toUtf8());
+ data = QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex();
+
+ return data;
+}
+}
+
+RunGuard::RunGuard(const QString &key)
+ : key(key)
+ , memLockKey(generateKeyHash(key, "_memLockKey"))
+ , sharedmemKey(generateKeyHash(key, "_sharedmemKey"))
+ , sharedMem(sharedmemKey)
+ , memLock(memLockKey, 1)
+{
+ memLock.acquire();
+ {
+ // Fix for *nix: http://habrahabr.ru/post/173281/
+ QSharedMemory fix(sharedmemKey);
+ fix.attach();
+ }
+
+ memLock.release();
+}
+
+RunGuard::~RunGuard() { release(); }
+
+bool
+RunGuard::isAnotherRunning()
+{
+ if (sharedMem.isAttached())
+ return false;
+
+ memLock.acquire();
+ const bool isRunning = sharedMem.attach();
+
+ if (isRunning)
+ sharedMem.detach();
+
+ memLock.release();
+
+ return isRunning;
+}
+
+bool
+RunGuard::tryToRun()
+{
+ // Extra check
+ if (isAnotherRunning())
+ return false;
+
+ memLock.acquire();
+ const bool result = sharedMem.create(sizeof(quint64));
+ memLock.release();
+
+ if (!result) {
+ release();
+ return false;
+ }
+
+ return true;
+}
+
+void
+RunGuard::release()
+{
+ memLock.acquire();
+
+ if (sharedMem.isAttached())
+ sharedMem.detach();
+
+ memLock.release();
+}
|