Skip to content

Commit

Permalink
Update SingleApplication from upstream (#228, #329)
Browse files Browse the repository at this point in the history
  • Loading branch information
variar committed Jun 1, 2021
1 parent d89b561 commit 854e9b0
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 93 deletions.
20 changes: 13 additions & 7 deletions 3rdparty/singleapp/include/singleapp/singleapplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,44 +85,44 @@ class SingleApplication : public QAPPLICATION_CLASS
* 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, const QString &userData = {} );
~SingleApplication() override;

/**
* @brief Returns if the instance is the primary instance
* @returns {bool}
*/
bool isPrimary();
bool isPrimary() const;

/**
* @brief Returns if the instance is a secondary instance
* @returns {bool}
*/
bool isSecondary();
bool isSecondary() const;

/**
* @brief Returns a unique identifier for the current instance
* @returns {qint32}
*/
quint32 instanceId();
quint32 instanceId() const;

/**
* @brief Returns the process ID (PID) of the primary instance
* @returns {qint64}
*/
qint64 primaryPid();
qint64 primaryPid() const;

/**
* @brief Returns the username of the user running the primary instance
* @returns {QString}
*/
QString primaryUser();
QString primaryUser() const;

/**
* @brief Returns the username of the current user
* @returns {QString}
*/
QString currentUser();
QString currentUser() const;

/**
* @brief Sends a message to the primary instance. Returns true on success.
Expand All @@ -133,6 +133,12 @@ class SingleApplication : public QAPPLICATION_CLASS
*/
bool sendMessage( const QByteArray &message, int timeout = 100 );

/**
* @brief Get the set user data.
* @returns {QStringList}
*/
QStringList userData() const;

Q_SIGNALS:
void instanceStarted();
void receivedMessage( quint32 instanceId, QByteArray message );
Expand Down
46 changes: 26 additions & 20 deletions 3rdparty/singleapp/src/singleapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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, const QString &userData )
: app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) )
{
Q_D( SingleApplication );
Expand All @@ -51,13 +51,17 @@ 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();

// To mitigate QSharedMemory issues with large amount of processes
// attempting to attach at the same time
d->randomSleep();
SingleApplicationPrivate::randomSleep();

#ifdef Q_OS_UNIX
// By explicitly attaching it and then deleting it we make sure that the
Expand Down Expand Up @@ -117,7 +121,7 @@ SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSeconda
qDebug() << "SingleApplication: Unable to unlock memory for random wait.";
qDebug() << d->memory->errorString();
}
d->randomSleep();
SingleApplicationPrivate::randomSleep();
if( ! d->memory->lock() ){
qCritical() << "SingleApplication: Unable to lock memory after random wait.";
abortSafely();
Expand Down Expand Up @@ -168,19 +172,19 @@ SingleApplication::~SingleApplication()
* Checks if the current application instance is primary.
* @return Returns true if the instance is primary, false otherwise.
*/
bool SingleApplication::isPrimary()
bool SingleApplication::isPrimary() const
{
Q_D( SingleApplication );
Q_D( const SingleApplication );
return d->server != nullptr;
}

/**
* Checks if the current application instance is secondary.
* @return Returns true if the instance is secondary, false otherwise.
*/
bool SingleApplication::isSecondary()
bool SingleApplication::isSecondary() const
{
Q_D( SingleApplication );
Q_D( const SingleApplication );
return d->server == nullptr;
}

Expand All @@ -190,9 +194,9 @@ bool SingleApplication::isSecondary()
* only incremented afterwards.
* @return Returns a unique instance id.
*/
quint32 SingleApplication::instanceId()
quint32 SingleApplication::instanceId() const
{
Q_D( SingleApplication );
Q_D( const SingleApplication );
return d->instanceNumber;
}

Expand All @@ -202,30 +206,29 @@ quint32 SingleApplication::instanceId()
* specific APIs.
* @return Returns the primary instance PID.
*/
qint64 SingleApplication::primaryPid()
qint64 SingleApplication::primaryPid() const
{
Q_D( SingleApplication );
Q_D( const SingleApplication );
return d->primaryPid();
}

/**
* Returns the username the primary instance is running as.
* @return Returns the username the primary instance is running as.
*/
QString SingleApplication::primaryUser()
QString SingleApplication::primaryUser() const
{
Q_D( SingleApplication );
Q_D( const SingleApplication );
return d->primaryUser();
}

/**
* Returns the username the current instance is running as.
* @return Returns the username the current instance is running as.
*/
QString SingleApplication::currentUser()
QString SingleApplication::currentUser() const
{
Q_D( SingleApplication );
return d->getUsername();
return SingleApplicationPrivate::getUsername();
}

/**
Expand All @@ -245,10 +248,7 @@ bool SingleApplication::sendMessage( const QByteArray &message, int timeout )
if( ! d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect ) )
return false;

d->socket->write( message );
bool dataWritten = d->socket->waitForBytesWritten( timeout );
d->socket->flush();
return dataWritten;
return d->writeConfirmedMessage( timeout, message );
}

/**
Expand All @@ -263,3 +263,9 @@ void SingleApplication::abortSafely()
delete d;
::exit( EXIT_FAILURE );
}

QStringList SingleApplication::userData() const
{
Q_D( const SingleApplication );
return d->appData();
}
Loading

0 comments on commit 854e9b0

Please sign in to comment.