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
```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
@ -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
used to notify the primary instance whenever a secondary instance had been
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
recognizes.*

View File

@ -36,7 +36,7 @@
* @param options Optional flags to toggle specific behaviour
* @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 ) )
{
Q_D( SingleApplication );
@ -51,6 +51,10 @@ SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSeconda
// Store the current mode of the program
d->options = options;
// Add any unique user data
if ( ! userData.isEmpty() )
d->addAppData( userData );
// Generating an application ID used for identifying the shared memory
// block and QLocalServer
d->genBlockServerName();
@ -262,3 +266,9 @@ void SingleApplication::abortSafely()
delete d;
::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.
* @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;
/**
@ -133,6 +133,12 @@ public:
*/
bool sendMessage( const QByteArray &message, int timeout = 100 );
/**
* @brief Get the set user data.
* @returns {QStringList}
*/
QStringList userData();
Q_SIGNALS:
void instanceStarted();
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::organizationDomain().toUtf8() );
if ( ! appDataList.isEmpty() )
appData.addData( appDataList.join( "" ).toUtf8() );
if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ){
appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() );
}
@ -186,9 +189,9 @@ void SingleApplicationPrivate::startPrimary()
// 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 );
server->setSocketOptions( QLocalServer::UserAccessOption );
} else {
server->setSocketOptions( QLocalServer::WorldAccessOption );
server->setSocketOptions( QLocalServer::WorldAccessOption );
}
server->listen( blockServerName );
@ -225,7 +228,7 @@ bool SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType conne
if( socket->state() != QLocalSocket::ConnectedState ){
while( true ){
randomSleep();
randomSleep();
if( socket->state() != QLocalSocket::ConnectingState )
socket->connectToServer( blockServerName );
@ -470,3 +473,13 @@ void SingleApplicationPrivate::randomSleep()
QThread::msleep( 8 + static_cast <unsigned long>( static_cast <float>( qrand() ) / RAND_MAX * 10 ));
#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 readInitMessageBody(QLocalSocket *socket);
static void randomSleep();
void addAppData(const QString &data);
QStringList appData() const;
SingleApplication *q_ptr;
QSharedMemory *memory;
@ -91,6 +93,7 @@ public:
QString blockServerName;
SingleApplication::Options options;
QMap<QLocalSocket*, ConnectionInfo> connectionMap;
QStringList appDataList;
public Q_SLOTS:
void slotConnectionEstablished();