Mercurial > hg > syntilista
view src/runguard.cpp @ 228:37d5f4329449
Implement single running instance check to prevent problems with the SQLite database.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 20 Mar 2018 13:45:21 +0200 |
parents | |
children |
line wrap: on
line source
// // Taken and modified from https://stackoverflow.com/questions/5006547/qt-best-practice-for-a-single-instance-app-protection // #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(); QSharedMemory fix(sharedmemKey); // Fix for *nix: http://habrahabr.ru/post/173281/ 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() { if (isAnotherRunning()) return false; memLock.acquire(); const bool result = sharedMem.create(sizeof(quint64)); memLock.release(); if (!result) release(); return result; } void RunGuard::release() { memLock.acquire(); if (sharedMem.isAttached()) sharedMem.detach(); memLock.release(); }