// // Created by Andrey Streltsov on 11/06/15. // Based on code from here: http://stackoverflow.com/a/28172162/365754 #include "AppRunGuard.h" #include 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; } } AppRunGuard::AppRunGuard( const QString& key ) : key( key ) , memLockKey( generateKeyHash( key, "_memLockKey" ) ) , sharedmemKey( generateKeyHash( key, "_sharedmemKey" ) ) , sharedMem( sharedmemKey ) , memLock( memLockKey, 1 ) { QSharedMemory fix( sharedmemKey ); // Fix for *nix: http://habrahabr.ru/post/173281/ fix.attach(); } AppRunGuard::~AppRunGuard() { release(); } bool AppRunGuard::isAnotherRunning() { if ( sharedMem.isAttached() ) return false; memLock.acquire(); const bool isRunning = sharedMem.attach(); if ( isRunning ) sharedMem.detach(); memLock.release(); return isRunning; } bool AppRunGuard::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 AppRunGuard::release() { memLock.acquire(); if ( sharedMem.isAttached() ) sharedMem.detach(); memLock.release(); }