| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- #include "vsingleinstanceguard.h"
- #include <QDebug>
- #include "utils/vutils.h"
- const QString VSingleInstanceGuard::c_memKey = "vnote_shared_memory";
- const int VSingleInstanceGuard::c_magic = 19910906;
- VSingleInstanceGuard::VSingleInstanceGuard()
- : m_online(false),
- m_sharedMemory(c_memKey)
- {
- }
- bool VSingleInstanceGuard::tryRun()
- {
- m_online = false;
- // If we can attach to the sharedmemory, there is another instance running.
- // In Linux, crashes may cause the shared memory segment remains. In this case,
- // this will attach to the old segment, then exit, freeing the old segment.
- if (m_sharedMemory.attach()) {
- qDebug() << "another instance is running";
- return false;
- }
- // Try to create it.
- bool ret = m_sharedMemory.create(sizeof(SharedStruct));
- if (ret) {
- // We created it.
- m_sharedMemory.lock();
- SharedStruct *str = (SharedStruct *)m_sharedMemory.data();
- str->m_magic = c_magic;
- str->m_filesBufIdx = 0;
- str->m_askedToShow = false;
- m_sharedMemory.unlock();
- m_online = true;
- return true;
- } else {
- qDebug() << "fail to create shared memory segment";
- return false;
- }
- }
- void VSingleInstanceGuard::openExternalFiles(const QStringList &p_files)
- {
- if (p_files.isEmpty()) {
- return;
- }
- if (!m_sharedMemory.isAttached()) {
- if (!m_sharedMemory.attach()) {
- qDebug() << "fail to attach to the shared memory segment"
- << (m_sharedMemory.error() ? m_sharedMemory.errorString() : "");
- return;
- }
- }
- qDebug() << "try to request another instance to open files" << p_files;
- int idx = 0;
- int tryCount = 100;
- while (tryCount--) {
- qDebug() << "set shared memory one round" << idx << "of" << p_files.size();
- m_sharedMemory.lock();
- SharedStruct *str = (SharedStruct *)m_sharedMemory.data();
- V_ASSERT(str->m_magic == c_magic);
- for (; idx < p_files.size(); ++idx) {
- if (p_files[idx].size() + 1 > FilesBufCount) {
- qDebug() << "skip file since its long name" << p_files[idx];
- // Skip this long long name file.
- continue;
- }
- if (!appendFileToBuffer(str, p_files[idx])) {
- break;
- }
- }
- m_sharedMemory.unlock();
- if (idx < p_files.size()) {
- VUtils::sleepWait(500);
- } else {
- break;
- }
- }
- }
- bool VSingleInstanceGuard::appendFileToBuffer(SharedStruct *p_str, const QString &p_file)
- {
- if (p_file.isEmpty()) {
- return true;
- }
- int strSize = p_file.size();
- if (strSize + 1 > FilesBufCount - p_str->m_filesBufIdx) {
- qDebug() << "no enough space for" << p_file;
- return false;
- }
- // Put the size first.
- p_str->m_filesBuf[p_str->m_filesBufIdx++] = (ushort)strSize;
- const QChar *data = p_file.constData();
- for (int i = 0; i < strSize; ++i) {
- p_str->m_filesBuf[p_str->m_filesBufIdx++] = data[i].unicode();
- }
- qDebug() << "after appended one file" << p_str->m_filesBufIdx << p_file;
- return true;
- }
- QStringList VSingleInstanceGuard::fetchFilesToOpen()
- {
- QStringList files;
- if (!m_online) {
- return files;
- }
- Q_ASSERT(m_sharedMemory.isAttached());
- m_sharedMemory.lock();
- SharedStruct *str = (SharedStruct *)m_sharedMemory.data();
- Q_ASSERT(str->m_magic == c_magic);
- Q_ASSERT(str->m_filesBufIdx <= FilesBufCount);
- int idx = 0;
- while (idx < str->m_filesBufIdx) {
- int strSize = str->m_filesBuf[idx++];
- Q_ASSERT(strSize <= str->m_filesBufIdx - idx);
- QString file;
- for (int i = 0; i < strSize; ++i) {
- file.append(QChar(str->m_filesBuf[idx++]));
- }
- files.append(file);
- }
- str->m_filesBufIdx = 0;
- m_sharedMemory.unlock();
- return files;
- }
- void VSingleInstanceGuard::showInstance()
- {
- if (!m_sharedMemory.isAttached()) {
- if (!m_sharedMemory.attach()) {
- qDebug() << "fail to attach to the shared memory segment"
- << (m_sharedMemory.error() ? m_sharedMemory.errorString() : "");
- return;
- }
- }
- m_sharedMemory.lock();
- SharedStruct *str = (SharedStruct *)m_sharedMemory.data();
- V_ASSERT(str->m_magic == c_magic);
- str->m_askedToShow = true;
- m_sharedMemory.unlock();
- qDebug() << "try to request another instance to show up";
- }
- bool VSingleInstanceGuard::fetchAskedToShow()
- {
- if (!m_online) {
- return false;
- }
- Q_ASSERT(m_sharedMemory.isAttached());
- m_sharedMemory.lock();
- SharedStruct *str = (SharedStruct *)m_sharedMemory.data();
- Q_ASSERT(str->m_magic == c_magic);
- bool ret = str->m_askedToShow;
- str->m_askedToShow = false;
- m_sharedMemory.unlock();
- return ret;
- }
- void VSingleInstanceGuard::exit()
- {
- if (!m_online) {
- return;
- }
- Q_ASSERT(m_sharedMemory.isAttached());
- m_sharedMemory.detach();
- m_online = false;
- }
|