/**************************************************************************** * * (c) 2009-2020 QGROUNDCONTROL PROJECT * * QGroundControl is licensed according to the terms in the file * COPYING.md in the root of the source code directory. * ****************************************************************************/ #include "RunGuard.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; } } 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(); }