Merge pull request #122 from LorenDB/master

Allow adding unique userdata to instances
This commit is contained in:
Itay Grudev 2020-12-17 11:47:01 +02:00 committed by GitHub
commit dc8042b5db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 7 deletions

View File

@ -154,7 +154,7 @@ API
### Members ### Members
```cpp ```cpp
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 100 ) SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 100, QString userData = QString() )
``` ```
Depending on whether `allowSecondary` is set, this constructor may terminate Depending on whether `allowSecondary` is set, this constructor may terminate
@ -163,7 +163,7 @@ can be specified to set whether the SingleApplication block should work
user-wide or system-wide. Additionally the `Mode::SecondaryNotification` may be user-wide or system-wide. Additionally the `Mode::SecondaryNotification` may be
used to notify the primary instance whenever a secondary instance had been used to notify the primary instance whenever a secondary instance had been
started (disabled by default). `timeout` specifies the maximum time in started (disabled by default). `timeout` specifies the maximum time in
milliseconds to wait for blocking operations. milliseconds to wait for blocking operations. Setting `userData` provides additional data that will isolate this instance from other instances that do not have the same (or any) user data set.
*__Note:__ `argc` and `argv` may be changed as Qt removes arguments that it *__Note:__ `argc` and `argv` may be changed as Qt removes arguments that it
recognizes.* recognizes.*

View File

@ -36,7 +36,7 @@
* @param options Optional flags to toggle specific behaviour * @param options Optional flags to toggle specific behaviour
* @param timeout Maximum time blocking functions are allowed during app load * @param timeout Maximum time blocking functions are allowed during app load
*/ */
SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout ) SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout, QString userData )
: app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) ) : app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) )
{ {
Q_D( SingleApplication ); Q_D( SingleApplication );
@ -51,6 +51,10 @@ SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSeconda
// Store the current mode of the program // Store the current mode of the program
d->options = options; d->options = options;
// Add any unique user data
if ( ! userData.isEmpty() )
d->addAppData( userData );
// Generating an application ID used for identifying the shared memory // Generating an application ID used for identifying the shared memory
// block and QLocalServer // block and QLocalServer
d->genBlockServerName(); d->genBlockServerName();
@ -262,3 +266,9 @@ void SingleApplication::abortSafely()
delete d; delete d;
::exit( EXIT_FAILURE ); ::exit( EXIT_FAILURE );
} }
QStringList SingleApplication::userData()
{
Q_D( SingleApplication );
return d->appData();
}

View File

@ -85,7 +85,7 @@ public:
* Usually 4*timeout would be the worst case (fail) scenario. * Usually 4*timeout would be the worst case (fail) scenario.
* @see See the corresponding QAPPLICATION_CLASS constructor for reference * @see See the corresponding QAPPLICATION_CLASS constructor for reference
*/ */
explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000 ); explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 1000, QString userData = QString() );
~SingleApplication() override; ~SingleApplication() override;
/** /**
@ -133,6 +133,12 @@ public:
*/ */
bool sendMessage( const QByteArray &message, int timeout = 100 ); bool sendMessage( const QByteArray &message, int timeout = 100 );
/**
* @brief Get the set user data.
* @returns {QStringList}
*/
QStringList userData();
Q_SIGNALS: Q_SIGNALS:
void instanceStarted(); void instanceStarted();
void receivedMessage( quint32 instanceId, QByteArray message ); void receivedMessage( quint32 instanceId, QByteArray message );

View File

@ -136,6 +136,9 @@ void SingleApplicationPrivate::genBlockServerName()
appData.addData( SingleApplication::app_t::organizationName().toUtf8() ); appData.addData( SingleApplication::app_t::organizationName().toUtf8() );
appData.addData( SingleApplication::app_t::organizationDomain().toUtf8() ); appData.addData( SingleApplication::app_t::organizationDomain().toUtf8() );
if ( ! appDataList.isEmpty() )
appData.addData( appDataList.join( "" ).toUtf8() );
if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ){ if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ){
appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() ); appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() );
} }
@ -186,9 +189,9 @@ void SingleApplicationPrivate::startPrimary()
// Restrict access to the socket according to the // Restrict access to the socket according to the
// SingleApplication::Mode::User flag on User level or no restrictions // SingleApplication::Mode::User flag on User level or no restrictions
if( options & SingleApplication::Mode::User ){ if( options & SingleApplication::Mode::User ){
server->setSocketOptions( QLocalServer::UserAccessOption ); server->setSocketOptions( QLocalServer::UserAccessOption );
} else { } else {
server->setSocketOptions( QLocalServer::WorldAccessOption ); server->setSocketOptions( QLocalServer::WorldAccessOption );
} }
server->listen( blockServerName ); server->listen( blockServerName );
@ -225,7 +228,7 @@ bool SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType conne
if( socket->state() != QLocalSocket::ConnectedState ){ if( socket->state() != QLocalSocket::ConnectedState ){
while( true ){ while( true ){
randomSleep(); randomSleep();
if( socket->state() != QLocalSocket::ConnectingState ) if( socket->state() != QLocalSocket::ConnectingState )
socket->connectToServer( blockServerName ); socket->connectToServer( blockServerName );
@ -470,3 +473,13 @@ void SingleApplicationPrivate::randomSleep()
QThread::msleep( 8 + static_cast <unsigned long>( static_cast <float>( qrand() ) / RAND_MAX * 10 )); QThread::msleep( 8 + static_cast <unsigned long>( static_cast <float>( qrand() ) / RAND_MAX * 10 ));
#endif #endif
} }
void SingleApplicationPrivate::addAppData(const QString &data)
{
appDataList.push_back(data);
}
QStringList SingleApplicationPrivate::appData() const
{
return appDataList;
}

View File

@ -82,6 +82,8 @@ public:
void readInitMessageHeader(QLocalSocket *socket); void readInitMessageHeader(QLocalSocket *socket);
void readInitMessageBody(QLocalSocket *socket); void readInitMessageBody(QLocalSocket *socket);
static void randomSleep(); static void randomSleep();
void addAppData(const QString &data);
QStringList appData() const;
SingleApplication *q_ptr; SingleApplication *q_ptr;
QSharedMemory *memory; QSharedMemory *memory;
@ -91,6 +93,7 @@ public:
QString blockServerName; QString blockServerName;
SingleApplication::Options options; SingleApplication::Options options;
QMap<QLocalSocket*, ConnectionInfo> connectionMap; QMap<QLocalSocket*, ConnectionInfo> connectionMap;
QStringList appDataList;
public Q_SLOTS: public Q_SLOTS:
void slotConnectionEstablished(); void slotConnectionEstablished();