forked from mirror/nheko
parent
7de5af83db
commit
65672d3dfb
@ -0,0 +1,31 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
//
|
||||||
|
// Taken from
|
||||||
|
// https://stackoverflow.com/questions/5006547/qt-best-practice-for-a-single-instance-app-protection
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <QObject> |
||||||
|
#include <QSharedMemory> |
||||||
|
#include <QSystemSemaphore> |
||||||
|
|
||||||
|
class RunGuard |
||||||
|
{ |
||||||
|
public: |
||||||
|
RunGuard(const QString &key); |
||||||
|
~RunGuard(); |
||||||
|
|
||||||
|
bool isAnotherRunning(); |
||||||
|
bool tryToRun(); |
||||||
|
void release(); |
||||||
|
|
||||||
|
private: |
||||||
|
const QString key; |
||||||
|
const QString memLockKey; |
||||||
|
const QString sharedmemKey; |
||||||
|
|
||||||
|
QSharedMemory sharedMem; |
||||||
|
QSystemSemaphore memLock; |
||||||
|
|
||||||
|
Q_DISABLE_COPY(RunGuard) |
||||||
|
}; |
@ -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(); |
||||||
|
} |
Loading…
Reference in new issue