* @brief Constructor. Checks and fires up LocalServer or closes the program * if another instance already exists * @param argc * @param argv * @param allowSecondary Whether to enable secondary instance support * @param options Optional flags to toggle specific behaviour * @param timeout Maximum time blocking functions are allowed during app load */
| 37 | * @param timeout Maximum time blocking functions are allowed during app load |
| 38 | */ |
| 39 | SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout, const QString &userData ) |
| 40 | : app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) ) |
| 41 | { |
| 42 | Q_D( SingleApplication ); |
| 43 | |
| 44 | #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) |
| 45 | // On Android and iOS since the library is not supported fallback to |
| 46 | // standard QApplication behaviour by simply returning at this point. |
| 47 | qWarning() << "SingleApplication is not supported on Android and iOS systems."; |
| 48 | return; |
| 49 | #endif |
| 50 | |
| 51 | // Store the current mode of the program |
| 52 | d->options = options; |
| 53 | |
| 54 | // Add any unique user data |
| 55 | if ( ! userData.isEmpty() ) |
| 56 | d->addAppData( userData ); |
| 57 | |
| 58 | // Generating an application ID used for identifying the shared memory |
| 59 | // block and QLocalServer |
| 60 | d->genBlockServerName(); |
| 61 | |
| 62 | // To mitigate QSharedMemory issues with large amount of processes |
| 63 | // attempting to attach at the same time |
| 64 | SingleApplicationPrivate::randomSleep(); |
| 65 | |
| 66 | #ifdef Q_OS_UNIX |
| 67 | // By explicitly attaching it and then deleting it we make sure that the |
| 68 | // memory is deleted even after the process has crashed on Unix. |
| 69 | d->memory = new QSharedMemory( d->blockServerName ); |
| 70 | d->memory->attach(); |
| 71 | delete d->memory; |
| 72 | #endif |
| 73 | // Guarantee thread safe behaviour with a shared memory block. |
| 74 | d->memory = new QSharedMemory( d->blockServerName ); |
| 75 | |
| 76 | // Create a shared memory block |
| 77 | if( d->memory->create( sizeof( InstancesInfo ) )){ |
| 78 | // Initialize the shared memory block |
| 79 | if( ! d->memory->lock() ){ |
| 80 | qCritical() << "SingleApplication: Unable to lock memory block after create."; |
| 81 | abortSafely(); |
| 82 | } |
| 83 | d->initializeMemoryBlock(); |
| 84 | } else { |
| 85 | if( d->memory->error() == QSharedMemory::AlreadyExists ){ |
| 86 | // Attempt to attach to the memory segment |
| 87 | if( ! d->memory->attach() ){ |
| 88 | qCritical() << "SingleApplication: Unable to attach to shared memory block."; |
| 89 | abortSafely(); |
| 90 | } |
| 91 | if( ! d->memory->lock() ){ |
| 92 | qCritical() << "SingleApplication: Unable to lock memory block after attach."; |
| 93 | abortSafely(); |
| 94 | } |
| 95 | } else { |
| 96 | qCritical() << "SingleApplication: Unable to create block."; |
nothing calls this directly
no test coverage detected