aboutsummaryrefslogtreecommitdiff
path: root/src/rungaurd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rungaurd.cpp')
-rw-r--r--src/rungaurd.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/rungaurd.cpp b/src/rungaurd.cpp
new file mode 100644
index 0000000..7136e7b
--- /dev/null
+++ b/src/rungaurd.cpp
@@ -0,0 +1,79 @@
+#include "rungaurd.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() ) // Extra check
+ 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();
+}