mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09:52 +08:00
support single instance app
Signed-off-by: Le Tan <tamlokveer@gmail.com>
This commit is contained in:
parent
3722e6cb71
commit
50db1a63ba
@ -3,9 +3,15 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
|
#include "vsingleinstanceguard.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
VSingleInstanceGuard guard;
|
||||||
|
if (!guard.tryRun()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
QTextCodec *codec = QTextCodec::codecForName("UTF8");
|
QTextCodec *codec = QTextCodec::codecForName("UTF8");
|
||||||
|
@ -43,7 +43,8 @@ SOURCES += main.cpp\
|
|||||||
vedittab.cpp \
|
vedittab.cpp \
|
||||||
voutline.cpp \
|
voutline.cpp \
|
||||||
vtoc.cpp \
|
vtoc.cpp \
|
||||||
vfilelocation.cpp
|
vfilelocation.cpp \
|
||||||
|
vsingleinstanceguard.cpp
|
||||||
|
|
||||||
HEADERS += vmainwindow.h \
|
HEADERS += vmainwindow.h \
|
||||||
vdirectorytree.h \
|
vdirectorytree.h \
|
||||||
@ -75,7 +76,8 @@ HEADERS += vmainwindow.h \
|
|||||||
vedittab.h \
|
vedittab.h \
|
||||||
voutline.h \
|
voutline.h \
|
||||||
vtoc.h \
|
vtoc.h \
|
||||||
vfilelocation.h
|
vfilelocation.h \
|
||||||
|
vsingleinstanceguard.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
vnote.qrc
|
vnote.qrc
|
||||||
|
73
src/vsingleinstanceguard.cpp
Normal file
73
src/vsingleinstanceguard.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include "vsingleinstanceguard.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
const QString VSingleInstanceGuard::m_memKey = "vnote_shared_memory";
|
||||||
|
const QString VSingleInstanceGuard::m_semKey = "vnote_semaphore";
|
||||||
|
const int VSingleInstanceGuard::m_magic = 133191933;
|
||||||
|
|
||||||
|
VSingleInstanceGuard::VSingleInstanceGuard()
|
||||||
|
: m_sharedMemory(m_memKey), m_sem(m_semKey, 1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VSingleInstanceGuard::~VSingleInstanceGuard()
|
||||||
|
{
|
||||||
|
if (m_sharedMemory.isAttached()) {
|
||||||
|
detachMemory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VSingleInstanceGuard::detachMemory()
|
||||||
|
{
|
||||||
|
m_sem.acquire();
|
||||||
|
m_sharedMemory.detach();
|
||||||
|
m_sem.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VSingleInstanceGuard::tryAttach()
|
||||||
|
{
|
||||||
|
m_sem.acquire();
|
||||||
|
bool ret = m_sharedMemory.attach();
|
||||||
|
m_sem.release();
|
||||||
|
if (ret) {
|
||||||
|
m_sharedMemory.lock();
|
||||||
|
SharedStruct *str = (SharedStruct *)m_sharedMemory.data();
|
||||||
|
str->m_activeRequest = 1;
|
||||||
|
m_sharedMemory.unlock();
|
||||||
|
detachMemory();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VSingleInstanceGuard::tryRun()
|
||||||
|
{
|
||||||
|
// If we can attach to the sharedmemory, there is another instance running.
|
||||||
|
if (tryAttach()) {
|
||||||
|
qDebug() << "Another instance is running";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to create it
|
||||||
|
m_sem.acquire();
|
||||||
|
bool ret = m_sharedMemory.create(sizeof(SharedStruct));
|
||||||
|
m_sem.release();
|
||||||
|
if (ret) {
|
||||||
|
// We created it
|
||||||
|
m_sharedMemory.lock();
|
||||||
|
SharedStruct *str = (SharedStruct *)m_sharedMemory.data();
|
||||||
|
str->m_magic = m_magic;
|
||||||
|
str->m_activeRequest = 0;
|
||||||
|
m_sharedMemory.unlock();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// Maybe another thread create it
|
||||||
|
if (tryAttach()) {
|
||||||
|
qDebug() << "Another instance is running";
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// Something wrong here
|
||||||
|
qWarning() << "error: failed to create or attach shared memory segment";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
src/vsingleinstanceguard.h
Normal file
33
src/vsingleinstanceguard.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef VSINGLEINSTANCEGUARD_H
|
||||||
|
#define VSINGLEINSTANCEGUARD_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QSharedMemory>
|
||||||
|
#include <QSystemSemaphore>
|
||||||
|
|
||||||
|
class VSingleInstanceGuard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VSingleInstanceGuard();
|
||||||
|
~VSingleInstanceGuard();
|
||||||
|
bool tryRun();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void detachMemory();
|
||||||
|
bool tryAttach();
|
||||||
|
|
||||||
|
struct SharedStruct {
|
||||||
|
// A magic number to identify if this struct is initialized
|
||||||
|
int m_magic;
|
||||||
|
// If it is 1, then another instance ask this instance to show itself
|
||||||
|
int m_activeRequest;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const QString m_memKey;
|
||||||
|
static const QString m_semKey;
|
||||||
|
static const int m_magic;
|
||||||
|
QSharedMemory m_sharedMemory;
|
||||||
|
QSystemSemaphore m_sem;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VSINGLEINSTANCEGUARD_H
|
Loading…
x
Reference in New Issue
Block a user