Improved the connectToPrimary() method and fixed issue with instanceStarted() not getting emitted

This commit is contained in:
Itay Grudev 2020-09-09 02:28:07 +01:00
parent eca5803665
commit 3e83f5ce13
3 changed files with 46 additions and 36 deletions

View File

@ -85,7 +85,7 @@ SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSeconda
abortSafely();
}
} else {
qCritical() << "SingleApplication: Unable create block.";
qCritical() << "SingleApplication: Unable to create block.";
abortSafely();
}
}
@ -238,7 +238,8 @@ bool SingleApplication::sendMessage( const QByteArray &message, int timeout )
if( isPrimary() ) return false;
// Make sure the socket is connected
d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect );
if( ! d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect ) )
return false;
d->socket->write( message );
bool dataWritten = d->socket->waitForBytesWritten( timeout );
@ -254,7 +255,7 @@ void SingleApplication::abortSafely()
{
Q_D( SingleApplication );
qCritical() << d->memory->errorString();
qCritical() << "SingleApplication: " << d->memory->error() << d->memory->errorString();
delete d;
::exit( EXIT_FAILURE );
}

View File

@ -208,59 +208,68 @@ void SingleApplicationPrivate::startSecondary()
instanceNumber = inst->secondary;
}
void SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType )
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 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 );
while( true ){
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);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
writeStream.setVersion(QDataStream::Qt_5_6);
writeStream.setVersion(QDataStream::Qt_5_6);
#endif
writeStream << blockServerName.toLatin1();
writeStream << static_cast<quint8>(connectionType);
writeStream << instanceNumber;
quint16 checksum = qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
writeStream << checksum;
writeStream << blockServerName.toLatin1();
writeStream << static_cast<quint8>(connectionType);
writeStream << instanceNumber;
quint16 checksum = qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
writeStream << checksum;
// The header indicates the message length that follows
QByteArray header;
QDataStream headerStream(&header, QIODevice::WriteOnly);
// 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);
headerStream.setVersion(QDataStream::Qt_5_6);
#endif
headerStream << static_cast <quint64>( initMsg.length() );
headerStream << static_cast <quint64>( initMsg.length() );
socket->write( header );
socket->write( initMsg );
socket->flush();
socket->waitForBytesWritten( msecs );
}
socket->write( header );
socket->write( initMsg );
socket->flush();
if( socket->waitForBytesWritten( timeout - time.elapsed() )) return true;
return false;
}
quint16 SingleApplicationPrivate::blockChecksum()

View File

@ -75,7 +75,7 @@ public:
void initializeMemoryBlock();
void startPrimary();
void startSecondary();
void connectToPrimary(int msecs, ConnectionType connectionType );
bool connectToPrimary(int msecs, ConnectionType connectionType );
quint16 blockChecksum();
qint64 primaryPid();
QString primaryUser();