blob: c79dfff89940c9dd9452e5f821f47803c54f665e [file] [log] [blame]
Andreas Traczyk45f56c92019-01-06 10:04:44 -05001// From: https://stackoverflow.com/a/28172162
2
3#include "runguard.h"
4
5#include <QCryptographicHash>
6
7namespace
8{
9
10QString generateKeyHash(const QString& key, const QString& salt)
11{
12 QByteArray data;
13
14 data.append(key.toUtf8());
15 data.append(salt.toUtf8());
16 data = QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex();
17
18 return data;
19}
20
21}
22
23RunGuard::RunGuard(const QString& key)
24 : key(key)
25 , memLockKey(generateKeyHash(key, "_memLockKey"))
26 , sharedmemKey(generateKeyHash(key, "_sharedmemKey"))
27 , sharedMem(sharedmemKey)
28 , memLock(memLockKey, 1)
29{
30 memLock.acquire();
31 {
32 QSharedMemory fix(sharedmemKey); // Fix for *nix: http://habrahabr.ru/post/173281/
33 fix.attach();
34 }
35 memLock.release();
36}
37
38RunGuard::~RunGuard()
39{
40 release();
41}
42
43bool RunGuard::isAnotherRunning()
44{
45 if (sharedMem.isAttached())
46 return false;
47
48 memLock.acquire();
49 const bool isRunning = sharedMem.attach();
50 if (isRunning)
51 sharedMem.detach();
52 memLock.release();
53
54 return isRunning;
55}
56
57bool RunGuard::tryToRun()
58{
59 if (isAnotherRunning()) // Extra check
60 return false;
61
62 memLock.acquire();
63 const bool result = sharedMem.create(sizeof(quint64));
64 memLock.release();
65 if (!result) {
66 release();
67 return false;
68 }
69
70 return true;
71}
72
73void RunGuard::release()
74{
75 memLock.acquire();
76 if (sharedMem.isAttached())
77 sharedMem.detach();
78 memLock.release();
79}