mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-08 23:26:40 +02:00
don't assume that exit() will clean up the stack
This commit is contained in:
@@ -8,11 +8,11 @@
|
|||||||
#define KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE 1024
|
#define KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE 1024
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
KDSingleApplicationGuard::Instance::Instance( const QStringList& args, qint64 p )
|
KDSingleApplicationGuard::Instance::Instance( const QStringList& args, qint64 p )
|
||||||
: arguments( args ),
|
: arguments( args ),
|
||||||
pid( p )
|
pid( p )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,31 +61,31 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* )
|
|||||||
using namespace kdtools;
|
using namespace kdtools;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class KDSingleApplicationGuard KDSingleApplicationGuard
|
* \class KDSingleApplicationGuard KDSingleApplicationGuard
|
||||||
\brief A guard to protect an application from having several instances.
|
* \brief A guard to protect an application from having several instances.
|
||||||
|
*
|
||||||
KDSingleApplicationGuard can be used to make sure only one instance of an
|
* KDSingleApplicationGuard can be used to make sure only one instance of an
|
||||||
application is running at the same time.
|
* application is running at the same time.
|
||||||
|
*
|
||||||
\note As KDSingleApplicationGuard uses QSharedMemory Qt 4.4 or later is required
|
* \note As KDSingleApplicationGuard uses QSharedMemory Qt 4.4 or later is required
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn void KDSingleApplicationGuard::instanceStarted()
|
* \fn void KDSingleApplicationGuard::instanceStarted()
|
||||||
This signal is emitted by the primary instance when ever one other
|
* This signal is emitted by the primary instance when ever one other
|
||||||
instance was started.
|
* instance was started.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn void KDSingleApplicationGuard::instanceExited()
|
* \fn void KDSingleApplicationGuard::instanceExited()
|
||||||
This signal is emitted by the primary instance when ever one other
|
* This signal is emitted by the primary instance when ever one other
|
||||||
instance was exited.
|
* instance was exited.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn void KDSingleApplicationGuard::becamePrimaryInstance()
|
* \fn void KDSingleApplicationGuard::becamePrimaryInstance()
|
||||||
This signal is emitted, when the current running application gets the new
|
* This signal is emitted, when the current running application gets the new
|
||||||
primary application. The old primary application has quit.
|
* primary application. The old primary application has quit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum Command
|
enum Command
|
||||||
@@ -105,8 +105,8 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( Commands )
|
|||||||
struct ProcessInfo
|
struct ProcessInfo
|
||||||
{
|
{
|
||||||
explicit ProcessInfo( Command c = FreeInstance, const QStringList& arguments = QStringList(), qint64 p = -1 )
|
explicit ProcessInfo( Command c = FreeInstance, const QStringList& arguments = QStringList(), qint64 p = -1 )
|
||||||
: command( c ),
|
: command( c ),
|
||||||
pid( p )
|
pid( p )
|
||||||
{
|
{
|
||||||
std::fill_n( commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE, '\0' );
|
std::fill_n( commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE, '\0' );
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ struct ProcessInfo
|
|||||||
bool operator==( const ProcessInfo& lhs, const ProcessInfo& rhs )
|
bool operator==( const ProcessInfo& lhs, const ProcessInfo& rhs )
|
||||||
{
|
{
|
||||||
return lhs.command == rhs.command &&
|
return lhs.command == rhs.command &&
|
||||||
::memcmp( lhs.commandline, rhs.commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE ) == 0;
|
::memcmp( lhs.commandline, rhs.commandline, KDSINGLEAPPLICATIONGUARD_MAX_COMMAND_LINE ) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=( const ProcessInfo& lhs, const ProcessInfo& rhs )
|
bool operator!=( const ProcessInfo& lhs, const ProcessInfo& rhs )
|
||||||
@@ -158,21 +158,21 @@ bool operator!=( const ProcessInfo& lhs, const ProcessInfo& rhs )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This struct contains information about the managed process system.
|
* This struct contains information about the managed process system.
|
||||||
\internal
|
* \internal
|
||||||
*/
|
*/
|
||||||
struct InstanceRegister
|
struct InstanceRegister
|
||||||
{
|
{
|
||||||
InstanceRegister( KDSingleApplicationGuard::Policy policy = KDSingleApplicationGuard::NoPolicy )
|
InstanceRegister( KDSingleApplicationGuard::Policy policy = KDSingleApplicationGuard::NoPolicy )
|
||||||
: policy( policy )
|
: policy( policy )
|
||||||
{
|
{
|
||||||
std::fill_n( info, KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() );
|
std::fill_n( info, KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() );
|
||||||
::memcpy( magicCookie, "kdsingleapp", 12 );
|
::memcpy( magicCookie, "kdsingleapp", 12 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns wheter this register was properly initialized by the first instance.
|
* Returns wheter this register was properly initialized by the first instance.
|
||||||
*/
|
*/
|
||||||
bool isValid() const
|
bool isValid() const
|
||||||
{
|
{
|
||||||
return ::strcmp( magicCookie, "kdsingleapp" ) == 0;
|
return ::strcmp( magicCookie, "kdsingleapp" ) == 0;
|
||||||
@@ -192,18 +192,18 @@ bool operator==( const InstanceRegister& lhs, const InstanceRegister& rhs )
|
|||||||
if( lhs.info[ i ] != rhs.info[ i ] )
|
if( lhs.info[ i ] != rhs.info[ i ] )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
* \internal
|
||||||
*/
|
*/
|
||||||
class KDSingleApplicationGuard::Private
|
class KDSingleApplicationGuard::Private
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Private( KDSingleApplicationGuard* qq )
|
Private( KDSingleApplicationGuard* qq )
|
||||||
: q( qq ),
|
: q( qq ),
|
||||||
id( -1 )
|
id( -1 )
|
||||||
{
|
{
|
||||||
if( primaryInstance == 0 )
|
if( primaryInstance == 0 )
|
||||||
primaryInstance = q;
|
primaryInstance = q;
|
||||||
@@ -258,28 +258,28 @@ void SIGINT_handler( int sig )
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Creates a new KDSingleApplicationGuard guarding \a parent from mulitply instances.
|
* Creates a new KDSingleApplicationGuard guarding \a parent from mulitply instances.
|
||||||
If \a policy is AutoKillOtherInstances (the default), all instances, which try to start,
|
* If \a policy is AutoKillOtherInstances (the default), all instances, which try to start,
|
||||||
are killed automatically and instanceStarted() is emitted.
|
* are killed automatically and instanceStarted() is emitted.
|
||||||
If \a policy is NoPolicy, the other instance will run and instanceStarted() is emitted.
|
* If \a policy is NoPolicy, the other instance will run and instanceStarted() is emitted.
|
||||||
*/
|
*/
|
||||||
KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Policy policy )
|
KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Policy policy )
|
||||||
: QObject( parent ),
|
: QObject( parent ),
|
||||||
d( new Private( this ) )
|
d( new Private( this ) )
|
||||||
{
|
{
|
||||||
const QString name = parent->applicationName();
|
const QString name = parent->applicationName();
|
||||||
Q_ASSERT_X( !name.isEmpty(), "KDSingleApplicationGuard::KDSingleApplicationGuard", "applicationName must not be emty" );
|
Q_ASSERT_X( !name.isEmpty(), "KDSingleApplicationGuard::KDSingleApplicationGuard", "applicationName must not be emty" );
|
||||||
d->mem.setKey( name );
|
d->mem.setKey( name );
|
||||||
|
|
||||||
// if another instance crashed, the shared memory segment is still there on Unix
|
// if another instance crashed, the shared memory segment is still there on Unix
|
||||||
// the following lines trigger deletion in that case
|
// the following lines trigger deletion in that case
|
||||||
#ifndef Q_WS_WIN
|
#ifndef Q_WS_WIN
|
||||||
d->mem.attach();
|
d->mem.attach();
|
||||||
d->mem.detach();
|
d->mem.detach();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
d->policy = policy;
|
d->policy = policy;
|
||||||
|
|
||||||
const bool created = d->mem.create( sizeof( InstanceRegister ) );
|
const bool created = d->mem.create( sizeof( InstanceRegister ) );
|
||||||
if( !created )
|
if( !created )
|
||||||
{
|
{
|
||||||
@@ -288,7 +288,7 @@ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Po
|
|||||||
qWarning( "KDSingleApplicationGuard: Could neither create nor attach to shared memory segment." );
|
qWarning( "KDSingleApplicationGuard: Could neither create nor attach to shared memory segment." );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lets wait till the other instance initialized the register
|
// lets wait till the other instance initialized the register
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
while( !initialized )
|
while( !initialized )
|
||||||
@@ -298,52 +298,57 @@ KDSingleApplicationGuard::KDSingleApplicationGuard( QCoreApplication* parent, Po
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool killMyself = false;
|
||||||
KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem );
|
|
||||||
|
|
||||||
if( !created )
|
|
||||||
{
|
{
|
||||||
// we're _not_ the first instance
|
KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem );
|
||||||
// but the
|
|
||||||
bool killOurSelf = false;
|
|
||||||
|
|
||||||
// find a new slot...
|
|
||||||
d->id = std::find( instances->info, instances->info + KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() ) - instances->info;
|
|
||||||
ProcessInfo& info = instances->info[ d->id ];
|
|
||||||
info = ProcessInfo( NewInstance, parent->arguments(), QCoreApplication::applicationPid() );
|
|
||||||
killOurSelf = instances->policy == AutoKillOtherInstances;
|
|
||||||
d->policy = instances->policy;
|
|
||||||
|
|
||||||
// but the signal that we tried to start was sent to the primary application
|
if( !created )
|
||||||
if( killOurSelf )
|
|
||||||
{
|
{
|
||||||
info.command |= ExitedInstance;
|
// we're _not_ the first instance
|
||||||
exit( 1 );
|
// but the
|
||||||
|
bool killOurSelf = false;
|
||||||
|
|
||||||
|
// find a new slot...
|
||||||
|
d->id = std::find( instances->info, instances->info + KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES, ProcessInfo() ) - instances->info;
|
||||||
|
ProcessInfo& info = instances->info[ d->id ];
|
||||||
|
info = ProcessInfo( NewInstance, parent->arguments(), QCoreApplication::applicationPid() );
|
||||||
|
killOurSelf = instances->policy == AutoKillOtherInstances;
|
||||||
|
d->policy = instances->policy;
|
||||||
|
|
||||||
|
// but the signal that we tried to start was sent to the primary application
|
||||||
|
if( killOurSelf )
|
||||||
|
{
|
||||||
|
info.command |= ExitedInstance;
|
||||||
|
killMyself = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ok.... we are the first instance
|
||||||
|
InstanceRegister reg( policy ); // create a new list
|
||||||
|
d->id = 0; // our id = 0
|
||||||
|
// and we've no command
|
||||||
|
reg.info[ 0 ] = ProcessInfo( NoCommand, parent->arguments(), QCoreApplication::applicationPid() );
|
||||||
|
*instances = reg; // push this is the process list into shared memory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
// call exit after we let the locker release our memory, as exit() is not guaranteed to clean up objects on the stack
|
||||||
{
|
if ( killMyself )
|
||||||
// ok.... we are the first instance
|
exit( 1 );
|
||||||
InstanceRegister reg( policy ); // create a new list
|
|
||||||
d->id = 0; // our id = 0
|
|
||||||
// and we've no command
|
|
||||||
reg.info[ 0 ] = ProcessInfo( NoCommand, parent->arguments(), QCoreApplication::applicationPid() );
|
|
||||||
*instances = reg; // push this is the process list into shared memory
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef Q_WS_WIN
|
#ifndef Q_WS_WIN
|
||||||
::signal( SIGINT, SIGINT_handler );
|
::signal( SIGINT, SIGINT_handler );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// now listen for commands
|
// now listen for commands
|
||||||
startTimer( 250 );
|
startTimer( 250 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Destroys this SingleApplicationGuard.
|
* Destroys this SingleApplicationGuard.
|
||||||
If this instance has been the primary instance and no other instance is existing anymore,
|
* If this instance has been the primary instance and no other instance is existing anymore,
|
||||||
the application is shut down completely. Otherwise the destructor selects another instance to
|
* the application is shut down completely. Otherwise the destructor selects another instance to
|
||||||
be the primary instances.
|
* be the primary instances.
|
||||||
*/
|
*/
|
||||||
KDSingleApplicationGuard::~KDSingleApplicationGuard()
|
KDSingleApplicationGuard::~KDSingleApplicationGuard()
|
||||||
{
|
{
|
||||||
@@ -352,16 +357,16 @@ KDSingleApplicationGuard::~KDSingleApplicationGuard()
|
|||||||
|
|
||||||
d->shutdownInstance();
|
d->shutdownInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
\property KDSingleApplicationGuard::primaryInstance
|
|
||||||
Determines wheter this instance is the primary instance.
|
|
||||||
The primary instance is the first instance which was started or an instance which
|
|
||||||
got selected by KDSingleApplicationGuard's destructor, when the primary instance was
|
|
||||||
shut down.
|
|
||||||
|
|
||||||
Get this property's value using %isPrimaryInstance(), and monitor changes to it
|
/*!
|
||||||
using becamePrimaryInstance().
|
* \property KDSingleApplicationGuard::primaryInstance
|
||||||
|
* Determines wheter this instance is the primary instance.
|
||||||
|
* The primary instance is the first instance which was started or an instance which
|
||||||
|
* got selected by KDSingleApplicationGuard's destructor, when the primary instance was
|
||||||
|
* shut down.
|
||||||
|
*
|
||||||
|
* Get this property's value using %isPrimaryInstance(), and monitor changes to it
|
||||||
|
* using becamePrimaryInstance().
|
||||||
*/
|
*/
|
||||||
bool KDSingleApplicationGuard::isPrimaryInstance() const
|
bool KDSingleApplicationGuard::isPrimaryInstance() const
|
||||||
{
|
{
|
||||||
@@ -369,12 +374,12 @@ bool KDSingleApplicationGuard::isPrimaryInstance() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\property KDSingleApplicationGuard::Policy
|
* \property KDSingleApplicationGuard::Policy
|
||||||
Specifies the policy KDSingleApplicationGuard is using when new instances are started.
|
* Specifies the policy KDSingleApplicationGuard is using when new instances are started.
|
||||||
This can only be set in the primary instance.
|
* This can only be set in the primary instance.
|
||||||
|
*
|
||||||
Get this property's value using %policy(), set it using %setPolicy(), and monitor changes
|
* Get this property's value using %policy(), set it using %setPolicy(), and monitor changes
|
||||||
to it using policyChanged().
|
* to it using policyChanged().
|
||||||
*/
|
*/
|
||||||
KDSingleApplicationGuard::Policy KDSingleApplicationGuard::policy() const
|
KDSingleApplicationGuard::Policy KDSingleApplicationGuard::policy() const
|
||||||
{
|
{
|
||||||
@@ -394,7 +399,7 @@ void KDSingleApplicationGuard::setPolicy( Policy policy )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns a list of all currently running instances.
|
* Returns a list of all currently running instances.
|
||||||
*/
|
*/
|
||||||
QList< KDSingleApplicationGuard::Instance > KDSingleApplicationGuard::instances() const
|
QList< KDSingleApplicationGuard::Instance > KDSingleApplicationGuard::instances() const
|
||||||
{
|
{
|
||||||
@@ -409,10 +414,10 @@ QList< KDSingleApplicationGuard::Instance > KDSingleApplicationGuard::instances(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Shuts down all other instances. This can only be called from the
|
* Shuts down all other instances. This can only be called from the
|
||||||
the primary instance.
|
* the primary instance.
|
||||||
Shut down is done gracefully via QCoreApplication::quit().
|
* Shut down is done gracefully via QCoreApplication::quit().
|
||||||
*/
|
*/
|
||||||
void KDSingleApplicationGuard::shutdownOtherInstances()
|
void KDSingleApplicationGuard::shutdownOtherInstances()
|
||||||
{
|
{
|
||||||
@@ -426,9 +431,9 @@ void KDSingleApplicationGuard::shutdownOtherInstances()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Kills all other instances. This can only be called from the
|
* Kills all other instances. This can only be called from the
|
||||||
the primary instance.
|
* the primary instance.
|
||||||
Killing is done via exit(1)
|
* Killing is done via exit(1)
|
||||||
*/
|
*/
|
||||||
void KDSingleApplicationGuard::killOtherInstances()
|
void KDSingleApplicationGuard::killOtherInstances()
|
||||||
{
|
{
|
||||||
@@ -442,7 +447,7 @@ void KDSingleApplicationGuard::killOtherInstances()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\reimp
|
* \reimp
|
||||||
*/
|
*/
|
||||||
void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
|
void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
|
||||||
{
|
{
|
||||||
@@ -456,11 +461,11 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
|
|||||||
|
|
||||||
{
|
{
|
||||||
KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem );
|
KDLockedSharedMemoryPointer< InstanceRegister > instances( &d->mem );
|
||||||
|
|
||||||
for( int i = 1; i < KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES; ++i )
|
for( int i = 1; i < KDSINGLEAPPLICATIONGUARD_NUMBER_OF_PROCESSES; ++i )
|
||||||
{
|
{
|
||||||
ProcessInfo& info = instances->info[ i ];
|
ProcessInfo& info = instances->info[ i ];
|
||||||
if( info.command & NewInstance )
|
if( info.command & NewInstance )
|
||||||
{
|
{
|
||||||
startedInstances.push_back( Instance( info.arguments(), info.pid ) );
|
startedInstances.push_back( Instance( info.arguments(), info.pid ) );
|
||||||
info.command &= ~NewInstance; // clear NewInstance flag
|
info.command &= ~NewInstance; // clear NewInstance flag
|
||||||
@@ -472,7 +477,7 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// one signal for every new instance - _after_ the memory segment was unlocked again
|
// one signal for every new instance - _after_ the memory segment was unlocked again
|
||||||
for( QList< Instance >::const_iterator it = startedInstances.begin(); it != startedInstances.end(); ++it )
|
for( QList< Instance >::const_iterator it = startedInstances.begin(); it != startedInstances.end(); ++it )
|
||||||
emit instanceStarted( *it );
|
emit instanceStarted( *it );
|
||||||
@@ -495,7 +500,7 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
|
|||||||
if( instances->info[ d->id ].command & BecomePrimaryCommand )
|
if( instances->info[ d->id ].command & BecomePrimaryCommand )
|
||||||
{
|
{
|
||||||
// we became primary!
|
// we became primary!
|
||||||
instances->info[ 0 ] = instances->info[ d->id ];
|
instances->info[ 0 ] = instances->info[ d->id ];
|
||||||
instances->info[ d->id ] = ProcessInfo(); // change our id to 0 and declare the old slot as free
|
instances->info[ d->id ] = ProcessInfo(); // change our id to 0 and declare the old slot as free
|
||||||
d->id = 0;
|
d->id = 0;
|
||||||
emit becamePrimaryInstance();
|
emit becamePrimaryInstance();
|
||||||
@@ -510,7 +515,7 @@ void KDSingleApplicationGuard::timerEvent( QTimerEvent* event )
|
|||||||
d->id = -1; // becauso our d'tor won't be called anymore
|
d->id = -1; // becauso our d'tor won't be called anymore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( killOurSelf ) // kill our self takes precedence
|
if( killOurSelf ) // kill our self takes precedence
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
else if( shutDownOurSelf )
|
else if( shutDownOurSelf )
|
||||||
@@ -590,14 +595,14 @@ KDAB_UNITTEST_SIMPLE( KDSingleApplicationGuard, "kdcoretools" ) {
|
|||||||
spy3 = new QSignalSpy( guard3, SIGNAL( becamePrimaryInstance() ) );
|
spy3 = new QSignalSpy( guard3, SIGNAL( becamePrimaryInstance() ) );
|
||||||
assertFalse( guard3->isPrimaryInstance() );
|
assertFalse( guard3->isPrimaryInstance() );
|
||||||
}
|
}
|
||||||
|
|
||||||
wait( 1000 );
|
wait( 1000 );
|
||||||
assertEqual( spy3->count(), 1 );
|
assertEqual( spy3->count(), 1 );
|
||||||
assertEqual( guard3->instances().count(), 1 );
|
assertEqual( guard3->instances().count(), 1 );
|
||||||
assertTrue( guard3->isPrimaryInstance() );
|
assertTrue( guard3->isPrimaryInstance() );
|
||||||
|
|
||||||
assertEqual( guard3->instances().first().arguments, qApp->arguments() );
|
assertEqual( guard3->instances().first().arguments, qApp->arguments() );
|
||||||
|
|
||||||
QSignalSpy spyStarted( guard3, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ) );
|
QSignalSpy spyStarted( guard3, SIGNAL( instanceStarted( KDSingleApplicationGuard::Instance ) ) );
|
||||||
QSignalSpy spyExited( guard3, SIGNAL( instanceExited( KDSingleApplicationGuard::Instance ) ) );
|
QSignalSpy spyExited( guard3, SIGNAL( instanceExited( KDSingleApplicationGuard::Instance ) ) );
|
||||||
|
|
||||||
@@ -609,13 +614,13 @@ KDAB_UNITTEST_SIMPLE( KDSingleApplicationGuard, "kdcoretools" ) {
|
|||||||
|
|
||||||
assertEqual( spyStarted.count(), 2 );
|
assertEqual( spyStarted.count(), 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
wait( 1000 );
|
wait( 1000 );
|
||||||
assertEqual( spyExited.count(), 2 );
|
assertEqual( spyExited.count(), 2 );
|
||||||
|
|
||||||
delete spy3;
|
delete spy3;
|
||||||
delete guard3;
|
delete guard3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // KDTOOLSCORE_UNITTESTS
|
#endif // KDTOOLSCORE_UNITTESTS
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user