forked from foldynl/QLog
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAppGuard.cpp
131 lines (106 loc) · 2.61 KB
/
AppGuard.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <QCryptographicHash>
#include <QLoggingCategory>
#if QT_VERSION >= QT_VERSION_CHECK(6,6,0)
#include <QNativeIpcKey>
#endif
#include "AppGuard.h"
#include "debug.h"
MODULE_IDENTIFICATION("qlog.core.appguard");
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;
}
}
AppGuard::AppGuard( const QString& key )
: key( key )
, memLockKey( generateKeyHash( key, "_memLockKey" ) )
, sharedmemKey( generateKeyHash( key, "_sharedmemKey" ) )
, sharedMem(
#if QT_VERSION >= QT_VERSION_CHECK(6,6,0)
QSharedMemory::legacyNativeKey(sharedmemKey)
#else
sharedmemKey
#endif
)
, memLock(
#if QT_VERSION >= QT_VERSION_CHECK(6,6,0)
QSystemSemaphore::legacyNativeKey(memLockKey),
#else
memLockKey,
#endif
1 )
{
FCT_IDENTIFICATION;
memLock.acquire();
{
// linux / unix shared memory is not freed when the application terminates abnormally,
// so you need to get rid of the garbage
QSharedMemory fix(
#if QT_VERSION >= QT_VERSION_CHECK(6,6,0)
QSharedMemory::legacyNativeKey(sharedmemKey)
#else
sharedmemKey
#endif
);
if ( fix.attach() )
{
fix.detach();
}
}
memLock.release();
}
AppGuard::~AppGuard()
{
release();
}
bool AppGuard::isAnotherRunning(void)
{
FCT_IDENTIFICATION;
if ( sharedMem.isAttached() )
return false;
memLock.acquire();
const bool isRunning = sharedMem.attach();
if ( isRunning )
{
sharedMem.detach();
}
memLock.release();
return isRunning;
}
bool AppGuard::tryToRun(void)
{
FCT_IDENTIFICATION;
if ( isAnotherRunning() ) // Extra check
{
return false;
}
memLock.acquire();
// The following 'attach' call is a workaround required for 'create' to run properly under QT 6.6 and MacOS.
// See more details about it in issue #257.
// It has no impact on other platforms and versions of Qt, therefore there is no compilation condition.
sharedMem.attach();
const bool result = sharedMem.create( sizeof( quint64 ) );
memLock.release();
if ( !result )
{
release();
return false;
}
return true;
}
void AppGuard::release(void)
{
FCT_IDENTIFICATION;
memLock.acquire();
if ( sharedMem.isAttached() )
{
sharedMem.detach();
}
memLock.release();
}