aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rungaurd.cpp79
-rw-r--r--src/rungaurd.h32
2 files changed, 111 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();
+}
diff --git a/src/rungaurd.h b/src/rungaurd.h
new file mode 100644
index 0000000..06d45a8
--- /dev/null
+++ b/src/rungaurd.h
@@ -0,0 +1,32 @@
+#ifndef RUNGUARD_H
+#define RUNGUARD_H
+
+#include <QObject>
+#include <QSharedMemory>
+#include <QSystemSemaphore>
+
+
+class RunGuard
+{
+
+public:
+ RunGuard( const QString& key );
+ ~RunGuard();
+
+ bool isAnotherRunning();
+ bool tryToRun();
+ void release();
+
+private:
+ const QString key;
+ const QString memLockKey;
+ const QString sharedmemKey;
+
+ QSharedMemory sharedMem;
+ QSystemSemaphore memLock;
+
+ Q_DISABLE_COPY( RunGuard )
+};
+
+
+#endif // RUNGUARD_H