aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--singleapplication_p.cpp75
-rw-r--r--singleapplication_p.h13
2 files changed, 58 insertions, 30 deletions
diff --git a/singleapplication_p.cpp b/singleapplication_p.cpp
index 365799e..1339728 100644
--- a/singleapplication_p.cpp
+++ b/singleapplication_p.cpp
@@ -263,29 +263,35 @@ bool SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType conne
#endif
writeStream << checksum;
- // The header indicates the message length that follows
+ return writeConfirmedMessage( static_cast<int>(msecs - time.elapsed()), initMsg );
+}
+
+void SingleApplicationPrivate::writeAck( QLocalSocket *sock ) {
+ sock->putChar('\n');
+}
+
+bool SingleApplicationPrivate::writeConfirmedMessage (int msecs, const QByteArray &msg)
+{
+ QElapsedTimer time;
+ time.start();
+
+ // Frame 1: The header indicates the message length that follows
QByteArray header;
QDataStream headerStream(&header, QIODevice::WriteOnly);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
headerStream.setVersion(QDataStream::Qt_5_6);
#endif
- headerStream << static_cast <quint64>( initMsg.length() );
+ headerStream << static_cast <quint64>( msg.length() );
- if( !writeConfirmedMessage( static_cast<int>(msecs - time.elapsed()), header ) )
+ if( ! writeConfirmedFrame( static_cast<int>(msecs - time.elapsed()), header ))
return false;
- if( !writeConfirmedMessage( static_cast<int>(msecs - time.elapsed()), initMsg ) )
- return false;
-
- return true;
-}
-
-void SingleApplicationPrivate::writeAck( QLocalSocket *sock ) {
- sock->putChar('\n');
+ // Frame 2: The message
+ return writeConfirmedFrame( static_cast<int>(msecs - time.elapsed()), msg );
}
-bool SingleApplicationPrivate::writeConfirmedMessage( int msecs, const QByteArray &msg )
+bool SingleApplicationPrivate::writeConfirmedFrame( int msecs, const QByteArray &msg )
{
socket->write( msg );
socket->flush();
@@ -360,13 +366,16 @@ void SingleApplicationPrivate::slotConnectionEstablished()
[nextConnSocket, this](){
auto &info = connectionMap[nextConnSocket];
switch(info.stage){
- case StageHeader:
- readInitMessageHeader(nextConnSocket);
+ case StageInitHeader:
+ readMessageHeader( nextConnSocket, StageInitBody );
break;
- case StageBody:
+ case StageInitBody:
readInitMessageBody(nextConnSocket);
break;
- case StageConnected:
+ case StageConnectedHeader:
+ readMessageHeader( nextConnSocket, StageConnectedBody );
+ break;
+ case StageConnectedBody:
this->slotDataAvailable( nextConnSocket, info.instanceId );
break;
default:
@@ -376,7 +385,7 @@ void SingleApplicationPrivate::slotConnectionEstablished()
);
}
-void SingleApplicationPrivate::readInitMessageHeader( QLocalSocket *sock )
+void SingleApplicationPrivate::readMessageHeader( QLocalSocket *sock, SingleApplicationPrivate::ConnectionStage nextStage )
{
if (!connectionMap.contains( sock )){
return;
@@ -396,27 +405,35 @@ void SingleApplicationPrivate::readInitMessageHeader( QLocalSocket *sock )
quint64 msgLen = 0;
headerStream >> msgLen;
ConnectionInfo &info = connectionMap[sock];
- info.stage = StageBody;
+ info.stage = nextStage;
info.msgLen = msgLen;
writeAck( sock );
}
-void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock )
+bool SingleApplicationPrivate::isFrameComplete( QLocalSocket *sock )
{
- Q_Q(SingleApplication);
-
if (!connectionMap.contains( sock )){
- return;
+ return false;
}
ConnectionInfo &info = connectionMap[sock];
if( sock->bytesAvailable() < ( qint64 )info.msgLen ){
- return;
+ return false;
}
+ return true;
+}
+
+void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock )
+{
+ Q_Q(SingleApplication);
+
+ if( !isFrameComplete( sock ) )
+ return;
+
// Read the message body
- QByteArray msgBytes = sock->read(info.msgLen);
+ QByteArray msgBytes = sock->readAll();
QDataStream readStream(msgBytes);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
@@ -456,8 +473,9 @@ void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock )
return;
}
+ ConnectionInfo &info = connectionMap[sock];
info.instanceId = instanceId;
- info.stage = StageConnected;
+ info.stage = StageConnectedHeader;
if( connectionType == NewInstance ||
( connectionType == SecondaryInstance &&
@@ -472,9 +490,16 @@ void SingleApplicationPrivate::readInitMessageBody( QLocalSocket *sock )
void SingleApplicationPrivate::slotDataAvailable( QLocalSocket *dataSocket, quint32 instanceId )
{
Q_Q(SingleApplication);
+
+ if ( !isFrameComplete( dataSocket ) )
+ return;
+
Q_EMIT q->receivedMessage( instanceId, dataSocket->readAll() );
writeAck( dataSocket );
+
+ ConnectionInfo &info = connectionMap[dataSocket];
+ info.stage = StageConnectedHeader;
}
void SingleApplicationPrivate::slotClientConnectionClosed( QLocalSocket *closedSocket, quint32 instanceId )
diff --git a/singleapplication_p.h b/singleapplication_p.h
index 0777c33..58507cf 100644
--- a/singleapplication_p.h
+++ b/singleapplication_p.h
@@ -61,9 +61,10 @@ public:
Reconnect = 3
};
enum ConnectionStage : quint8 {
- StageHeader = 0,
- StageBody = 1,
- StageConnected = 2,
+ StageInitHeader = 0,
+ StageInitBody = 1,
+ StageConnectedHeader = 2,
+ StageConnectedBody = 3,
};
Q_DECLARE_PUBLIC(SingleApplication)
@@ -79,10 +80,12 @@ public:
quint16 blockChecksum() const;
qint64 primaryPid() const;
QString primaryUser() const;
- void readInitMessageHeader(QLocalSocket *socket);
+ bool isFrameComplete(QLocalSocket *sock);
+ void readMessageHeader(QLocalSocket *socket, ConnectionStage nextStage);
void readInitMessageBody(QLocalSocket *socket);
- bool writeConfirmedMessage(int msecs, const QByteArray &msg);
void writeAck(QLocalSocket *sock);
+ bool writeConfirmedFrame(int msecs, const QByteArray &msg);
+ bool writeConfirmedMessage(int msecs, const QByteArray &msg);
static void randomSleep();
void addAppData(const QString &data);
QStringList appData() const;