#include #include "qsingleapplication.h" #define QSA_SHMSIZE 4096 #define QSA_MSGSIZE (QSA_SHMSIZE - sizeof(quint32) - sizeof(quint32)) QSingleApplication::QSingleApplication(const QString & app_name): QThread() { shm.setKey(app_name); exiting = false; first = !shm.attach(); if (!first) { shm.detach(); first = !shm.attach(); if (!first) return; } shm.create(QSA_SHMSIZE); shm.attach(); shm.lock(); void * d = shm.data(); if (d) memset(d, 0, sizeof(quint32)); shm.unlock(); start(); //qDebug() << "start listen"; } QSingleApplication::~QSingleApplication() { if (first) { exiting = true; quit(); if (!wait(100)) terminate(); } if (shm.isAttached()) shm.detach(); } void QSingleApplication::sendMessage(const QByteArray & m) { //qDebug() << "send message" << first << shm.isAttached(); if (first || !shm.isAttached()) return; if (m.size() > int(QSA_MSGSIZE)) { qDebug() << "[QSingleApplication] Too large message:" << m.size() << ">" << QSA_MSGSIZE; return; } shm.lock(); quint32 num(0), size = m.size(); void * d = shm.data(); if (d) { memcpy(&num, d, sizeof(quint32)); num++; memcpy(d, &num, sizeof(quint32)); memcpy((((char*)d) + sizeof(quint32)), &size, sizeof(quint32)); memcpy((((char*)d) + sizeof(quint32) + sizeof(quint32)), m.constData(), size); } shm.unlock(); } void QSingleApplication::run() { quint32 num(0), pnum(0), size(0); while (!exiting) { shm.lock(); const void * d = shm.constData(); if (d) { memcpy(&num, d, sizeof(quint32)); if (pnum != num) { pnum = num; //qDebug() << "new message" << num; memcpy(&size, (((const char*)d) + sizeof(quint32)), sizeof(quint32)); if (size <= int(QSA_MSGSIZE)) { QByteArray msg; msg.resize(size); memcpy(msg.data(), (((const char*)d) + sizeof(quint32) + sizeof(quint32)), size); emit messageReceived(msg); } else { qDebug() << "[QSingleApplication] Invalid message size:" << size; } } } shm.unlock(); if (exiting) break; msleep(10); } }