From 35ee984d7239244a757f77e8621d4983d08fbc6c Mon Sep 17 00:00:00 2001 From: Vlad Pyatnichenko Date: Fri, 4 Mar 2016 20:15:13 +0200 Subject: Adaptation to Qt's pimpl idiom design. Improved inheritance safety. Details: * Improved unsafe C-style macros inheritance approach to the project-wide DEFINES: it is unspecified in which order source files are being preprocessed ones, so in singleapplication.cpp the class might be inherent of default-specified base, while in main.cpp this can be a user-provided QAPPLICATION_CLASS definition. * Replace Qt's pseudo-keywords to more library-independent counterparts ('emit -> Q_EMIT', etc) * Indentation fixes (80 character column-width) * Rearragned #include statements: from most platform-independen to more app-specific. * Fixed some grammar typos. * README.md updated respectively. --- singleapplication.cpp | 66 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 26 deletions(-) (limited to 'singleapplication.cpp') diff --git a/singleapplication.cpp b/singleapplication.cpp index 0bcbc12..451857d 100644 --- a/singleapplication.cpp +++ b/singleapplication.cpp @@ -1,16 +1,21 @@ -#include "singleapplication.h" +#include + #include #include #include #include -#include #ifdef Q_OS_UNIX #include #include #endif +#include "singleapplication.h" + + class SingleApplicationPrivate { + Q_DECLARE_PUBLIC(SingleApplication) + public: SingleApplicationPrivate(SingleApplication *q_ptr) : q_ptr(q_ptr) { } @@ -18,7 +23,7 @@ public: { // Start a QLocalServer to listen for connections server = new QLocalServer(); - server->removeServer(serverName); + QLocalServer::removeServer(serverName); server->listen(serverName); QObject::connect(server, SIGNAL(newConnection()), q_ptr, SLOT(slotConnectionEstablished())); } @@ -27,8 +32,8 @@ public: void crashHandler() { // This guarantees the program will work even with multiple - // instances of SingleApplication in different threads - // Which in my opinion is idiotic, but lets handle that too + // instances of SingleApplication in different threads. + // Which in my opinion is idiotic, but lets handle that too. { sharedMemMutex.lock(); sharedMem.append(memory); @@ -38,9 +43,9 @@ public: // QSharedMemory block is deleted even if the process crashes signal(SIGSEGV, SingleApplicationPrivate::terminate); signal(SIGABRT, SingleApplicationPrivate::terminate); - signal(SIGFPE, SingleApplicationPrivate::terminate); - signal(SIGILL, SingleApplicationPrivate::terminate); - signal(SIGINT, SingleApplicationPrivate::terminate); + signal(SIGFPE, SingleApplicationPrivate::terminate); + signal(SIGILL, SingleApplicationPrivate::terminate); + signal(SIGINT, SingleApplicationPrivate::terminate); signal(SIGTERM, SingleApplicationPrivate::terminate); } @@ -75,38 +80,43 @@ public: * @param argv */ SingleApplication::SingleApplication(int &argc, char *argv[]) - : QAPPLICATION_CLASS(argc, argv), d_ptr(new SingleApplicationPrivate(this)) + : app_t(argc, argv), d_ptr(new SingleApplicationPrivate(this)) { - QString serverName = QAPPLICATION_CLASS::organizationName() + QAPPLICATION_CLASS::applicationName(); + Q_D(SingleApplication); + + QString serverName = app_t::organizationName() + app_t::applicationName(); serverName.replace(QRegExp("[^\\w\\-. ]"), ""); - // Garantee thread safe behaviour with a shared memory block - d_ptr->memory = new QSharedMemory(serverName); + // Guarantee thread safe behaviour with a shared memory block + d->memory = new QSharedMemory(serverName); // Create a shared memory block with a minimum size of 1 byte - if( d_ptr->memory->create(1, QSharedMemory::ReadOnly) ) + if( d->memory->create(1, QSharedMemory::ReadOnly) ) { #ifdef Q_OS_UNIX // Handle any further termination signals to ensure the // QSharedMemory block is deleted even if the process crashes - d_ptr->crashHandler(); + d->crashHandler(); #endif // Successful creation means that no main process exists // So we start a Local Server to listen for connections - d_ptr->startServer(serverName); + d->startServer(serverName); } else { // Connect to the Local Server of the main process to notify it // that a new process had been started - d_ptr->socket = new QLocalSocket(); - d_ptr->socket->connectToServer(serverName); + d->socket = new QLocalSocket(); + d->socket->connectToServer(serverName); - // Even though a shared memory block exists, the original application might have crashed - // So only after a successful connection is the second instance terminated - if( d_ptr->socket->waitForConnected(100) ) + // Even though a shared memory block exists, the original application + // might have crashed. + // So only after a successful connection is the second instance + // terminated. + if( d->socket->waitForConnected(100) ) { - ::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function + // Terminate the program using STDLib's exit function. + ::exit(EXIT_SUCCESS); } else { - delete d_ptr->memory; + delete d->memory; ::exit(EXIT_SUCCESS); } } @@ -117,8 +127,10 @@ SingleApplication::SingleApplication(int &argc, char *argv[]) */ SingleApplication::~SingleApplication() { - delete d_ptr->memory; - d_ptr->server->close(); + Q_D(SingleApplication); + + delete d->memory; + d->server->close(); } /** @@ -126,8 +138,10 @@ SingleApplication::~SingleApplication() */ void SingleApplication::slotConnectionEstablished() { - QLocalSocket *socket = d_ptr->server->nextPendingConnection(); + Q_D(SingleApplication); + + QLocalSocket *socket = d->server->nextPendingConnection(); socket->close(); delete socket; - emit showUp(); + Q_EMIT showUp(); } -- cgit v1.2.1 From 27df0ec8d012dca64dc0937649c39015f5d421f8 Mon Sep 17 00:00:00 2001 From: Vlad Pyatnichenko Date: Sun, 6 Mar 2016 01:09:04 +0200 Subject: HOTFIX: added Qt's modules prefixes to #include statements. --- singleapplication.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'singleapplication.cpp') diff --git a/singleapplication.cpp b/singleapplication.cpp index 451857d..32269d4 100644 --- a/singleapplication.cpp +++ b/singleapplication.cpp @@ -1,9 +1,9 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include #ifdef Q_OS_UNIX #include -- cgit v1.2.1 From 7a3858a2148b60500f7a8ce26b5047ff34bee42c Mon Sep 17 00:00:00 2001 From: Vlad Pyatnichenko Date: Tue, 22 Mar 2016 01:32:20 +0200 Subject: HOTFIX: use Q_Q instead of q_ptr directly. --- singleapplication.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'singleapplication.cpp') diff --git a/singleapplication.cpp b/singleapplication.cpp index 32269d4..1c0d921 100644 --- a/singleapplication.cpp +++ b/singleapplication.cpp @@ -21,11 +21,13 @@ public: void startServer(QString &serverName) { + Q_Q(SingleApplication); + // Start a QLocalServer to listen for connections server = new QLocalServer(); QLocalServer::removeServer(serverName); server->listen(serverName); - QObject::connect(server, SIGNAL(newConnection()), q_ptr, SLOT(slotConnectionEstablished())); + QObject::connect(server, SIGNAL(newConnection()), q, SLOT(slotConnectionEstablished())); } #ifdef Q_OS_UNIX -- cgit v1.2.1 From 8eb993a7f81428b816d47887cd60139d1dfa7fff Mon Sep 17 00:00:00 2001 From: Vlad Pyatnichenko Date: Tue, 5 Apr 2016 20:31:05 +0300 Subject: Ensure backward compatibility and some cosmetic changes. --- singleapplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'singleapplication.cpp') diff --git a/singleapplication.cpp b/singleapplication.cpp index 1c0d921..27e2bb1 100644 --- a/singleapplication.cpp +++ b/singleapplication.cpp @@ -115,7 +115,7 @@ SingleApplication::SingleApplication(int &argc, char *argv[]) // terminated. if( d->socket->waitForConnected(100) ) { - // Terminate the program using STDLib's exit function. + // Terminate the program using STDLib's exit function ::exit(EXIT_SUCCESS); } else { delete d->memory; -- cgit v1.2.1