diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rungaurd.cpp | 79 | ||||
-rw-r--r-- | src/rungaurd.h | 32 |
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 |