Entropy Piano Tuner  1.1.3 (documentation not yet complete)
An open-source experimental software for piano tuning by entropy minimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
runguard.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright 2015 Haye Hinrichsen, Christoph Wick
3  *
4  * This file is part of Entropy Piano Tuner.
5  *
6  * Entropy Piano Tuner is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * Entropy Piano Tuner is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * Entropy Piano Tuner. If not, see http://www.gnu.org/licenses/.
18  *****************************************************************************/
19 
20 //============================================================================
21 // RunGuard, preventing multiple instances of the application
22 //============================================================================
23 
24 #include "runguard.h"
25 
26 #include <QCryptographicHash>
27 
29 
30 //-----------------------------------------------------------------------------
31 // Constructor
32 //-----------------------------------------------------------------------------
33 
38 
39 RunGuard::RunGuard( const QString& key )
40  : key (key)
41  , memLockKey (generateKeyHash( key, "_memLockKey" ))
42  , sharedmemKey (generateKeyHash( key, "_sharedmemKey"))
43  , sharedMem (sharedmemKey)
44  , memLock (memLockKey, 1)
45 {
46  QSharedMemory fix (sharedmemKey); // Fix for *nix: http://habrahabr.ru/post/173281/
47  fix.attach();
48 }
49 
50 //-----------------------------------------------------------------------------
51 // Generate hash string
52 //-----------------------------------------------------------------------------
53 
63 
64 QString RunGuard::generateKeyHash( const QString& key, const QString& salt )
65 {
66  QByteArray data;
67 
68  data.append( key.toUtf8() );
69  data.append( salt.toUtf8() );
70  data = QCryptographicHash::hash( data, QCryptographicHash::Sha1 ).toHex();
71 
72  return data;
73 }
74 
75 
76 //-----------------------------------------------------------------------------
77 // Check whether antoher instance is running
78 //-----------------------------------------------------------------------------
79 
90 
92 {
93  // If the shared memory is already attached to the own instance
94  // there is certainly no other application running.
95  if (sharedMem.isAttached()) return false;
96 
97  // Otherwise, we have to check whether another instance has
98  // already created the shared memory. To find that out we
99  // try to attach ourselves. If this is possible
100  // it indicates that another application has already created the
101  // shared memory. If so, we detach immediately afterwards.
102  memLock.acquire();
103  const bool sharedMemAlreadyExists = sharedMem.attach();
104  if (sharedMemAlreadyExists) sharedMem.detach();
105  memLock.release();
106  return sharedMemAlreadyExists;
107 }
108 
109 
110 //-----------------------------------------------------------------------------
111 // Try to run
112 //-----------------------------------------------------------------------------
113 
121 
123 {
124  if (isAnotherRunning()) return false; // Extra check
125 
126  memLock.acquire();
127  const bool success = sharedMem.create( sizeof( quint64 ) );
128  memLock.release();
129  if (not success) release();
130  return success;
131 }
132 
133 //-----------------------------------------------------------------------------
134 // Release current application
135 //-----------------------------------------------------------------------------
136 
143 
145 {
146  memLock.acquire();
147  if (sharedMem.isAttached()) sharedMem.detach();
148  memLock.release();
149 }
bool isAnotherRunning()
Check whether another instance of the application is running.
Definition: runguard.cpp:91
void release()
Release the running application.
Definition: runguard.cpp:144
const QString sharedmemKey
Key labelling the shared memory.
Definition: runguard.h:57
bool tryToRun()
Try to run the applicaiton, return false if another instance is running.
Definition: runguard.cpp:122
QSystemSemaphore memLock
Lock used when shared memory is accessed.
Definition: runguard.h:60
QString generateKeyHash(const QString &key, const QString &salt)
Generate hash string for a given keys.
Definition: runguard.cpp:64
QSharedMemory sharedMem
Shared memory labelled by a given key.
Definition: runguard.h:59
RunGuard(const QString &key)
Constructor for a run guard.
Definition: runguard.cpp:39