Skip to content
Snippets Groups Projects
RunGuard.cpp 1.58 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "RunGuard.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();
            {
                    // Fix for *nix: http://habrahabr.ru/post/173281/
                    QSharedMemory fix(sharedmemKey);
                    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()
    {
            // Extra check
            if (isAnotherRunning())
                    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();
    }