From 65672d3dfbdf179df520bbaa5e7e7ba28a27db20 Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Thu, 14 Dec 2017 21:55:00 +0200 Subject: Allow only one application instance fixes #141 --- src/RunGuard.cc | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/RunGuard.cc (limited to 'src/RunGuard.cc') 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 + +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(); +} -- cgit 1.5.1