Skip to content

Instantly share code, notes, and snippets.

@andrey-str
Created September 11, 2016 12:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andrey-str/8a7a4575d8bcc2cd45e982190555027b to your computer and use it in GitHub Desktop.
Save andrey-str/8a7a4575d8bcc2cd45e982190555027b to your computer and use it in GitHub Desktop.
//
// Created by Andrey Streltsov on 11/06/15.
// Based on code from here: http://stackoverflow.com/a/28172162/365754
#include "AppRunGuard.h"
#include <qcryptographichash.h>
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();
}
//
// Created by Andrey Streltsov on 11/06/15.
// Based on code from here: http://stackoverflow.com/a/28172162/365754
#ifndef RUNGUARD_H
#define RUNGUARD_H
#include <QString>
#include <qsharedmemory.h>
#include <qsystemsemaphore.h>
class AppRunGuard : public QObject {
public:
AppRunGuard( const QString& key );
virtual ~AppRunGuard();
bool isAnotherRunning();
bool tryToRun();
void release();
private:
const QString key;
const QString memLockKey;
const QString sharedmemKey;
QSharedMemory sharedMem;
QSystemSemaphore memLock;
Q_DISABLE_COPY(AppRunGuard)
};
#endif // RUNGUARD_H
//
// Created by Andrey Streltsov on 11/06/15.
// Usage example
#define kAppRunUUID "your-app-instance-uuid-here"
int main(int argc, char *argv[]) {
AppRunGuard guard(kAppRunUUID);
if ( !guard.tryToRun() )
return 1;
QApplication app(argc, argv);
return app.exec();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment