Update singleapplication
This commit is contained in:
375
3rdparty/singleapplication/singleapplication_p.cpp
vendored
375
3rdparty/singleapplication/singleapplication_p.cpp
vendored
@@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) Itay Grudev 2015 - 2018
|
||||
// Copyright (c) Itay Grudev 2015 - 2020
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -44,6 +44,8 @@
|
||||
# include <pwd.h>
|
||||
#endif
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QIODevice>
|
||||
#include <QSharedMemory>
|
||||
#include <QByteArray>
|
||||
@@ -52,6 +54,12 @@
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
#include <QDir>
|
||||
#include <QElapsedTimer>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
# include <QRandomGenerator>
|
||||
#else
|
||||
# include <QDateTime>
|
||||
#endif
|
||||
|
||||
#include "singleapplication.h"
|
||||
#include "singleapplication_p.h"
|
||||
@@ -61,32 +69,74 @@
|
||||
# include <lmcons.h>
|
||||
#endif
|
||||
|
||||
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication *_q_ptr)
|
||||
: q_ptr(_q_ptr),
|
||||
memory(nullptr),
|
||||
socket(nullptr),
|
||||
server(nullptr),
|
||||
instanceNumber(-1) {}
|
||||
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication *ptr)
|
||||
: q_ptr(ptr),
|
||||
memory_(nullptr),
|
||||
socket_(nullptr),
|
||||
server_(nullptr),
|
||||
instanceNumber_(-1) {}
|
||||
|
||||
SingleApplicationPrivate::~SingleApplicationPrivate() {
|
||||
|
||||
if (socket != nullptr) {
|
||||
socket->close();
|
||||
delete socket;
|
||||
if (socket_ != nullptr) {
|
||||
socket_->close();
|
||||
delete socket_;
|
||||
socket_ = nullptr;
|
||||
}
|
||||
|
||||
memory->lock();
|
||||
InstancesInfo *inst = static_cast<InstancesInfo *>(memory->data());
|
||||
if (server != nullptr) {
|
||||
server->close();
|
||||
delete server;
|
||||
inst->primary = false;
|
||||
inst->primaryPid = -1;
|
||||
inst->checksum = blockChecksum();
|
||||
}
|
||||
memory->unlock();
|
||||
if (memory_ != nullptr) {
|
||||
memory_->lock();
|
||||
InstancesInfo *inst = static_cast<InstancesInfo*>(memory_->data());
|
||||
if (server_ != nullptr) {
|
||||
server_->close();
|
||||
delete server_;
|
||||
inst->primary = false;
|
||||
inst->primaryPid = -1;
|
||||
inst->primaryUser[0] = '\0';
|
||||
inst->checksum = blockChecksum();
|
||||
}
|
||||
memory_->unlock();
|
||||
|
||||
delete memory_;
|
||||
memory_ = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString SingleApplicationPrivate::getUsername() {
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
QString username;
|
||||
#if defined(HAVE_GETEUID) && defined(HAVE_GETPWUID)
|
||||
struct passwd *pw = getpwuid(geteuid());
|
||||
if (pw) {
|
||||
username = QString::fromLocal8Bit(pw->pw_name);
|
||||
}
|
||||
#endif
|
||||
if (username.isEmpty()) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
username = qEnvironmentVariable("USER");
|
||||
#else
|
||||
username = QString::fromLocal8Bit(qgetenv("USER"));
|
||||
#endif
|
||||
}
|
||||
return username;
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
wchar_t username[UNLEN + 1];
|
||||
// Specifies size of the buffer on input
|
||||
DWORD usernameLength = UNLEN + 1;
|
||||
if (GetUserNameW(username, &usernameLength)) {
|
||||
return QString::fromWCharArray(username);
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
return qEnvironmentVariable("USERNAME");
|
||||
#else
|
||||
return QString::fromLocal8Bit(qgetenv("USERNAME"));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
delete memory;
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::genBlockServerName() {
|
||||
@@ -97,11 +147,11 @@ void SingleApplicationPrivate::genBlockServerName() {
|
||||
appData.addData(SingleApplication::app_t::organizationName().toUtf8());
|
||||
appData.addData(SingleApplication::app_t::organizationDomain().toUtf8());
|
||||
|
||||
if (!(options & SingleApplication::Mode::ExcludeAppVersion)) {
|
||||
if (!(options_ & SingleApplication::Mode::ExcludeAppVersion)) {
|
||||
appData.addData(SingleApplication::app_t::applicationVersion().toUtf8());
|
||||
}
|
||||
|
||||
if (!(options & SingleApplication::Mode::ExcludeAppPath)) {
|
||||
if (!(options_ & SingleApplication::Mode::ExcludeAppPath)) {
|
||||
#ifdef Q_OS_WIN
|
||||
appData.addData(SingleApplication::app_t::applicationFilePath().toLower().toUtf8());
|
||||
#else
|
||||
@@ -110,153 +160,162 @@ void SingleApplicationPrivate::genBlockServerName() {
|
||||
}
|
||||
|
||||
// User level block requires a user specific data in the hash
|
||||
if (options & SingleApplication::Mode::User) {
|
||||
#ifdef Q_OS_UNIX
|
||||
QByteArray username;
|
||||
# if defined(HAVE_GETEUID) && defined(HAVE_GETPWUID)
|
||||
struct passwd *pw = getpwuid(geteuid());
|
||||
if (pw) {
|
||||
username = pw->pw_name;
|
||||
}
|
||||
# endif
|
||||
if (username.isEmpty()) username = qgetenv("USER");
|
||||
appData.addData(username);
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
wchar_t username[UNLEN + 1];
|
||||
// Specifies size of the buffer on input
|
||||
DWORD usernameLength = UNLEN + 1;
|
||||
if (GetUserNameW(username, &usernameLength)) {
|
||||
appData.addData(QString::fromWCharArray(username).toUtf8());
|
||||
}
|
||||
else {
|
||||
appData.addData(qgetenv("USERNAME"));
|
||||
}
|
||||
#endif
|
||||
if (options_ & SingleApplication::Mode::User) {
|
||||
appData.addData(getUsername().toUtf8());
|
||||
}
|
||||
|
||||
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with server naming requirements.
|
||||
blockServerName = appData.result().toBase64().replace("/", "_");
|
||||
blockServerName_ = appData.result().toBase64().replace("/", "_");
|
||||
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::initializeMemoryBlock() {
|
||||
|
||||
InstancesInfo *inst = static_cast<InstancesInfo *>(memory->data());
|
||||
InstancesInfo *inst = static_cast<InstancesInfo*>(memory_->data());
|
||||
inst->primary = false;
|
||||
inst->secondary = 0;
|
||||
inst->primaryPid = -1;
|
||||
inst->primaryUser[0] = '\0';
|
||||
inst->checksum = blockChecksum();
|
||||
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::startPrimary() {
|
||||
|
||||
Q_Q(SingleApplication);
|
||||
|
||||
// Successful creation means that no main process exists
|
||||
// So we start a QLocalServer to listen for connections
|
||||
QLocalServer::removeServer(blockServerName);
|
||||
server = new QLocalServer();
|
||||
|
||||
// Restrict access to the socket according to the
|
||||
// SingleApplication::Mode::User flag on User level or no restrictions
|
||||
if (options & SingleApplication::Mode::User) {
|
||||
server->setSocketOptions(QLocalServer::UserAccessOption);
|
||||
}
|
||||
else {
|
||||
server->setSocketOptions(QLocalServer::WorldAccessOption);
|
||||
}
|
||||
|
||||
server->listen(blockServerName);
|
||||
QObject::connect(server, &QLocalServer::newConnection, this, &SingleApplicationPrivate::slotConnectionEstablished);
|
||||
|
||||
// Reset the number of connections
|
||||
InstancesInfo *inst = static_cast<InstancesInfo *>(memory->data());
|
||||
InstancesInfo *inst = static_cast<InstancesInfo*>(memory_->data());
|
||||
|
||||
inst->primary = true;
|
||||
inst->primaryPid = q->applicationPid();
|
||||
qstrncpy(inst->primaryUser, getUsername().toUtf8().data(), sizeof(inst->primaryUser));
|
||||
inst->checksum = blockChecksum();
|
||||
instanceNumber_ = 0;
|
||||
// Successful creation means that no main process exists
|
||||
// So we start a QLocalServer to listen for connections
|
||||
QLocalServer::removeServer(blockServerName_);
|
||||
server_ = new QLocalServer();
|
||||
|
||||
// Restrict access to the socket according to the SingleApplication::Mode::User flag on User level or no restrictions
|
||||
if (options_ & SingleApplication::Mode::User) {
|
||||
server_->setSocketOptions(QLocalServer::UserAccessOption);
|
||||
}
|
||||
else {
|
||||
server_->setSocketOptions(QLocalServer::WorldAccessOption);
|
||||
}
|
||||
|
||||
server_->listen(blockServerName_);
|
||||
QObject::connect(server_, &QLocalServer::newConnection, this, &SingleApplicationPrivate::slotConnectionEstablished);
|
||||
|
||||
instanceNumber = 0;
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::startSecondary() {}
|
||||
void SingleApplicationPrivate::startSecondary() {
|
||||
|
||||
void SingleApplicationPrivate::connectToPrimary(const int msecs, const ConnectionType connectionType) {
|
||||
InstancesInfo *inst = static_cast<InstancesInfo*>(memory_->data());
|
||||
|
||||
inst->secondary += 1;
|
||||
inst->checksum = blockChecksum();
|
||||
instanceNumber_ = inst->secondary;
|
||||
|
||||
}
|
||||
|
||||
bool SingleApplicationPrivate::connectToPrimary(int timeout, ConnectionType connectionType) {
|
||||
|
||||
QElapsedTimer time;
|
||||
time.start();
|
||||
|
||||
// Connect to the Local Server of the Primary Instance if not already connected.
|
||||
if (socket == nullptr) {
|
||||
socket = new QLocalSocket();
|
||||
if (socket_ == nullptr) {
|
||||
socket_ = new QLocalSocket();
|
||||
}
|
||||
|
||||
// If already connected - we are done;
|
||||
if (socket->state() == QLocalSocket::ConnectedState)
|
||||
return;
|
||||
if (socket_->state() == QLocalSocket::ConnectedState) return true;
|
||||
|
||||
// If not connect
|
||||
if (socket->state() == QLocalSocket::UnconnectedState ||
|
||||
socket->state() == QLocalSocket::ClosingState) {
|
||||
socket->connectToServer(blockServerName);
|
||||
}
|
||||
if (socket_->state() != QLocalSocket::ConnectedState) {
|
||||
|
||||
// Wait for being connected
|
||||
if (socket->state() == QLocalSocket::ConnectingState) {
|
||||
socket->waitForConnected(msecs);
|
||||
forever {
|
||||
randomSleep();
|
||||
|
||||
if (socket_->state() != QLocalSocket::ConnectingState)
|
||||
socket_->connectToServer(blockServerName_);
|
||||
|
||||
if (socket_->state() == QLocalSocket::ConnectingState) {
|
||||
socket_->waitForConnected(timeout - time.elapsed());
|
||||
}
|
||||
|
||||
// If connected break out of the loop
|
||||
if (socket_->state() == QLocalSocket::ConnectedState) break;
|
||||
|
||||
// If elapsed time since start is longer than the method timeout return
|
||||
if (time.elapsed() >= timeout) return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialisation message according to the SingleApplication protocol
|
||||
if (socket->state() == QLocalSocket::ConnectedState) {
|
||||
// Notify the parent that a new instance had been started;
|
||||
QByteArray initMsg;
|
||||
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
|
||||
QByteArray initMsg;
|
||||
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
|
||||
writeStream.setVersion(QDataStream::Qt_5_8);
|
||||
|
||||
writeStream.setVersion(QDataStream::Qt_5_6);
|
||||
writeStream << blockServerName_.toLatin1();
|
||||
writeStream << static_cast<quint8>(connectionType);
|
||||
writeStream << instanceNumber_;
|
||||
|
||||
writeStream << blockServerName.toLatin1();
|
||||
writeStream << static_cast<quint8>(connectionType);
|
||||
writeStream << instanceNumber;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
quint16 checksum = qChecksum(initMsg);
|
||||
quint16 checksum = qChecksum(QByteArray(initMsg, static_cast<quint32>(initMsg.length())));
|
||||
#else
|
||||
quint16 checksum = qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
|
||||
quint16 checksum = qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
|
||||
#endif
|
||||
writeStream << checksum;
|
||||
|
||||
// The header indicates the message length that follows
|
||||
QByteArray header;
|
||||
QDataStream headerStream(&header, QIODevice::WriteOnly);
|
||||
writeStream << checksum;
|
||||
|
||||
headerStream.setVersion(QDataStream::Qt_5_6);
|
||||
// The header indicates the message length that follows
|
||||
QByteArray header;
|
||||
QDataStream headerStream(&header, QIODevice::WriteOnly);
|
||||
headerStream.setVersion(QDataStream::Qt_5_8);
|
||||
headerStream << static_cast<quint64>(initMsg.length());
|
||||
|
||||
headerStream << static_cast<quint64>(initMsg.length());
|
||||
socket_->write(header);
|
||||
socket_->write(initMsg);
|
||||
socket_->flush();
|
||||
if (socket_->waitForBytesWritten(timeout - time.elapsed())) return true;
|
||||
|
||||
return false;
|
||||
|
||||
socket->write(header);
|
||||
socket->write(initMsg);
|
||||
socket->flush();
|
||||
socket->waitForBytesWritten(msecs);
|
||||
}
|
||||
}
|
||||
|
||||
quint16 SingleApplicationPrivate::blockChecksum() {
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
quint16 checksum = qChecksum(QByteArray(static_cast<const char *>(memory->constData()), offsetof(InstancesInfo, checksum)));
|
||||
quint16 checksum = qChecksum(QByteArray(static_cast<const char*>(memory_->constData()), offsetof(InstancesInfo, checksum)));
|
||||
#else
|
||||
quint16 checksum = qChecksum(static_cast<const char *>(memory->constData()), offsetof(InstancesInfo, checksum));
|
||||
quint16 checksum = qChecksum(static_cast<const char*>(memory_->constData()), offsetof(InstancesInfo, checksum));
|
||||
#endif
|
||||
|
||||
return checksum;
|
||||
|
||||
}
|
||||
|
||||
qint64 SingleApplicationPrivate::primaryPid() {
|
||||
|
||||
qint64 pid;
|
||||
|
||||
memory->lock();
|
||||
InstancesInfo *inst = static_cast<InstancesInfo *>(memory->data());
|
||||
pid = inst->primaryPid;
|
||||
memory->unlock();
|
||||
memory_->lock();
|
||||
InstancesInfo *inst = static_cast<InstancesInfo*>(memory_->data());
|
||||
qint64 pid = inst->primaryPid;
|
||||
memory_->unlock();
|
||||
|
||||
return pid;
|
||||
|
||||
}
|
||||
|
||||
QString SingleApplicationPrivate::primaryUser() {
|
||||
|
||||
memory_->lock();
|
||||
InstancesInfo *inst = static_cast<InstancesInfo*>(memory_->data());
|
||||
QByteArray username = inst->primaryUser;
|
||||
memory_->unlock();
|
||||
|
||||
return QString::fromUtf8(username);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,43 +323,41 @@ qint64 SingleApplicationPrivate::primaryPid() {
|
||||
*/
|
||||
void SingleApplicationPrivate::slotConnectionEstablished() {
|
||||
|
||||
QLocalSocket *nextConnSocket = server->nextPendingConnection();
|
||||
connectionMap.insert(nextConnSocket, ConnectionInfo());
|
||||
QLocalSocket *nextConnSocket = server_->nextPendingConnection();
|
||||
connectionMap_.insert(nextConnSocket, ConnectionInfo());
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::aboutToClose,
|
||||
[nextConnSocket, this]() {
|
||||
auto &info = connectionMap[nextConnSocket];
|
||||
Q_EMIT this->slotClientConnectionClosed(nextConnSocket, info.instanceId);
|
||||
});
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::aboutToClose, [nextConnSocket, this]() {
|
||||
auto &info = connectionMap_[nextConnSocket];
|
||||
Q_EMIT this->slotClientConnectionClosed(nextConnSocket, info.instanceId);
|
||||
});
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::disconnected,
|
||||
[nextConnSocket, this]() {
|
||||
connectionMap.remove(nextConnSocket);
|
||||
nextConnSocket->deleteLater();
|
||||
});
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::disconnected, [nextConnSocket, this]() {
|
||||
connectionMap_.remove(nextConnSocket);
|
||||
nextConnSocket->deleteLater();
|
||||
});
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::readyRead, [nextConnSocket, this]() {
|
||||
auto &info = connectionMap_[nextConnSocket];
|
||||
switch (info.stage) {
|
||||
case StageHeader:
|
||||
readInitMessageHeader(nextConnSocket);
|
||||
break;
|
||||
case StageBody:
|
||||
readInitMessageBody(nextConnSocket);
|
||||
break;
|
||||
case StageConnected:
|
||||
Q_EMIT this->slotDataAvailable(nextConnSocket, info.instanceId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
});
|
||||
|
||||
QObject::connect(nextConnSocket, &QLocalSocket::readyRead,
|
||||
[nextConnSocket, this]() {
|
||||
auto &info = connectionMap[nextConnSocket];
|
||||
switch (info.stage) {
|
||||
case StageHeader:
|
||||
readInitMessageHeader(nextConnSocket);
|
||||
break;
|
||||
case StageBody:
|
||||
readInitMessageBody(nextConnSocket);
|
||||
break;
|
||||
case StageConnected:
|
||||
Q_EMIT this->slotDataAvailable(nextConnSocket, info.instanceId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::readInitMessageHeader(QLocalSocket *sock) {
|
||||
|
||||
if (!connectionMap.contains(sock)) {
|
||||
if (!connectionMap_.contains(sock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -309,30 +366,30 @@ void SingleApplicationPrivate::readInitMessageHeader(QLocalSocket *sock) {
|
||||
}
|
||||
|
||||
QDataStream headerStream(sock);
|
||||
|
||||
headerStream.setVersion(QDataStream::Qt_5_6);
|
||||
headerStream.setVersion(QDataStream::Qt_5_8);
|
||||
|
||||
// Read the header to know the message length
|
||||
quint64 msgLen = 0;
|
||||
headerStream >> msgLen;
|
||||
ConnectionInfo &info = connectionMap[sock];
|
||||
ConnectionInfo &info = connectionMap_[sock];
|
||||
info.stage = StageBody;
|
||||
info.msgLen = msgLen;
|
||||
|
||||
if (sock->bytesAvailable() >= static_cast<qint64>(msgLen)) {
|
||||
readInitMessageBody(sock);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::readInitMessageBody(QLocalSocket *sock) {
|
||||
|
||||
Q_Q(SingleApplication);
|
||||
|
||||
if (!connectionMap.contains(sock)) {
|
||||
if (!connectionMap_.contains(sock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectionInfo &info = connectionMap[sock];
|
||||
ConnectionInfo &info = connectionMap_[sock];
|
||||
if (sock->bytesAvailable() < static_cast<qint64>(info.msgLen)) {
|
||||
return;
|
||||
}
|
||||
@@ -340,8 +397,7 @@ void SingleApplicationPrivate::readInitMessageBody(QLocalSocket *sock) {
|
||||
// Read the message body
|
||||
QByteArray msgBytes = sock->read(info.msgLen);
|
||||
QDataStream readStream(msgBytes);
|
||||
|
||||
readStream.setVersion(QDataStream::Qt_5_6);
|
||||
readStream.setVersion(QDataStream::Qt_5_8);
|
||||
|
||||
// server name
|
||||
QByteArray latin1Name;
|
||||
@@ -362,12 +418,12 @@ void SingleApplicationPrivate::readInitMessageBody(QLocalSocket *sock) {
|
||||
readStream >> msgChecksum;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
const quint16 actualChecksum = qChecksum(msgBytes);
|
||||
const quint16 actualChecksum = qChecksum(QByteArray(msgBytes, static_cast<quint32>(msgBytes.length() - sizeof(quint16))));
|
||||
#else
|
||||
const quint16 actualChecksum = qChecksum(msgBytes.constData(), static_cast<quint32>(msgBytes.length() - sizeof(quint16)));
|
||||
#endif
|
||||
|
||||
bool isValid = readStream.status() == QDataStream::Ok && QLatin1String(latin1Name) == blockServerName && msgChecksum == actualChecksum;
|
||||
bool isValid = readStream.status() == QDataStream::Ok && QLatin1String(latin1Name) == blockServerName_ && msgChecksum == actualChecksum;
|
||||
|
||||
if (!isValid) {
|
||||
sock->close();
|
||||
@@ -377,23 +433,38 @@ void SingleApplicationPrivate::readInitMessageBody(QLocalSocket *sock) {
|
||||
info.instanceId = instanceId;
|
||||
info.stage = StageConnected;
|
||||
|
||||
if (connectionType == NewInstance || (connectionType == SecondaryInstance && options & SingleApplication::Mode::SecondaryNotification)) {
|
||||
if (connectionType == NewInstance || (connectionType == SecondaryInstance && options_ & SingleApplication::Mode::SecondaryNotification)) {
|
||||
Q_EMIT q->instanceStarted();
|
||||
}
|
||||
|
||||
if (sock->bytesAvailable() > 0) {
|
||||
Q_EMIT this->slotDataAvailable(sock, instanceId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::slotDataAvailable(QLocalSocket *dataSocket, const quint32 instanceId) {
|
||||
|
||||
Q_Q(SingleApplication);
|
||||
Q_EMIT q->receivedMessage(instanceId, dataSocket->readAll());
|
||||
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::slotClientConnectionClosed(QLocalSocket *closedSocket, const quint32 instanceId) {
|
||||
|
||||
if (closedSocket->bytesAvailable() > 0)
|
||||
if (closedSocket->bytesAvailable() > 0) {
|
||||
Q_EMIT slotDataAvailable(closedSocket, instanceId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SingleApplicationPrivate::randomSleep() {
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||
QThread::msleep(QRandomGenerator::global()->bounded(8u, 18u));
|
||||
#else
|
||||
qsrand(QDateTime::currentMSecsSinceEpoch() % std::numeric_limits<uint>::max());
|
||||
QThread::msleep(8 + static_cast<unsigned long>(static_cast<float>(qrand()) / RAND_MAX * 10));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user