modernize: Replace most remaining old-style connects by PMF ones
[quassel.git] / src / core / core.cpp
index 9b7af58..556eec6 100644 (file)
@@ -36,9 +36,8 @@
 #include "types.h"
 #include "util.h"
 
-// Currently building with LDAP bindings is optional.
 #ifdef HAVE_LDAP
-#include "ldapauthenticator.h"
+#  include "ldapauthenticator.h"
 #endif
 
 // migration related
@@ -67,21 +66,11 @@ public:
 // ==============================
 //  Core
 // ==============================
-Core *Core::_instance{nullptr};
-
-Core *Core::instance()
-{
-    return _instance;
-}
-
 
 Core::Core()
+    : Singleton<Core>{this}
 {
-    if (_instance) {
-        qWarning() << "Recreating core instance!";
-        delete _instance;
-    }
-    _instance = this;
+    Q_INIT_RESOURCE(sql);
 
     // Parent all QObject-derived attributes, so when the Core instance gets moved into another
     // thread, they get moved with it
@@ -93,11 +82,9 @@ Core::Core()
 
 Core::~Core()
 {
-    saveState();
     qDeleteAll(_connectingClients);
     qDeleteAll(_sessions);
     syncStorage();
-    _instance = nullptr;
 }
 
 
@@ -105,10 +92,6 @@ void Core::init()
 {
     _startTime = QDateTime::currentDateTime().toUTC(); // for uptime :)
 
-    if (Quassel::runMode() == Quassel::RunMode::CoreOnly) {
-        Quassel::loadTranslation(QLocale::system());
-    }
-
     // check settings version
     // so far, we only have 1
     CoreSettings s;
@@ -238,12 +221,12 @@ void Core::init()
             return false;
         });
 
-        connect(&_storageSyncTimer, SIGNAL(timeout()), this, SLOT(syncStorage()));
+        connect(&_storageSyncTimer, &QTimer::timeout, this, &Core::syncStorage);
         _storageSyncTimer.start(10 * 60 * 1000); // 10 minutes
     }
 
-    connect(&_server, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
-    connect(&_v6server, SIGNAL(newConnection()), this, SLOT(incomingConnection()));
+    connect(&_server, &QTcpServer::newConnection, this, &Core::incomingConnection);
+    connect(&_v6server, &QTcpServer::newConnection, this, &Core::incomingConnection);
 
     if (!startListening()) {
         throw ExitException{EXIT_FAILURE, tr("Cannot open port for listening!")};
@@ -273,6 +256,39 @@ void Core::initAsync()
 }
 
 
+void Core::shutdown()
+{
+    quInfo() << "Core shutting down...";
+
+    saveState();
+
+    for (auto &&client : _connectingClients) {
+        client->deleteLater();
+    }
+    _connectingClients.clear();
+
+    if (_sessions.isEmpty()) {
+        emit shutdownComplete();
+        return;
+    }
+
+    for (auto &&session : _sessions) {
+        connect(session, &SessionThread::shutdownComplete, this, &Core::onSessionShutdown);
+        session->shutdown();
+    }
+}
+
+
+void Core::onSessionShutdown(SessionThread *session)
+{
+    _sessions.take(_sessions.key(session))->deleteLater();
+    if (_sessions.isEmpty()) {
+        quInfo() << "Core shutdown complete!";
+        emit shutdownComplete();
+    }
+}
+
+
 /*** Session Restore ***/
 
 void Core::saveState()
@@ -427,7 +443,7 @@ bool Core::initStorage(const QString &backend, const QVariantMap &settings,
         return false;
     }
 
-    connect(storage.get(), SIGNAL(dbUpgradeInProgress(bool)), this, SIGNAL(dbUpgradeInProgress(bool)));
+    connect(storage.get(), &Storage::dbUpgradeInProgress, this, &Core::dbUpgradeInProgress);
 
     Storage::State storageState = storage->init(settings, environment, loadFromEnvironment);
     switch (storageState) {
@@ -449,8 +465,8 @@ bool Core::initStorage(const QString &backend, const QVariantMap &settings,
     case Storage::IsReady:
         // delete all other backends
         _registeredStorageBackends.clear();
-        connect(storage.get(), SIGNAL(bufferInfoUpdated(UserId, const BufferInfo &)),
-                this, SIGNAL(bufferInfoUpdated(UserId, const BufferInfo &)));
+        connect(storage.get(), &Storage::bufferInfoUpdated,
+                this, &Core::bufferInfoUpdated);
         break;
     }
     _storage = std::move(storage);
@@ -561,7 +577,7 @@ bool Core::initAuthenticator(const QString &backend, const QVariantMap &settings
 bool Core::sslSupported()
 {
 #ifdef HAVE_SSL
-    SslServer *sslServer = qobject_cast<SslServer *>(&instance()->_server);
+    auto *sslServer = qobject_cast<SslServer *>(&instance()->_server);
     return sslServer && sslServer->isCertValid();
 #else
     return false;
@@ -572,10 +588,10 @@ bool Core::sslSupported()
 bool Core::reloadCerts()
 {
 #ifdef HAVE_SSL
-    SslServer *sslServerv4 = qobject_cast<SslServer *>(&_server);
+    auto *sslServerv4 = qobject_cast<SslServer *>(&_server);
     bool retv4 = sslServerv4->reloadCerts();
 
-    SslServer *sslServerv6 = qobject_cast<SslServer *>(&_v6server);
+    auto *sslServerv6 = qobject_cast<SslServer *>(&_v6server);
     bool retv6 = sslServerv6->reloadCerts();
 
     return retv4 && retv6;
@@ -720,17 +736,17 @@ void Core::stopListening(const QString &reason)
 
 void Core::incomingConnection()
 {
-    QTcpServer *server = qobject_cast<QTcpServer *>(sender());
+    auto *server = qobject_cast<QTcpServer *>(sender());
     Q_ASSERT(server);
     while (server->hasPendingConnections()) {
         QTcpSocket *socket = server->nextPendingConnection();
 
-        CoreAuthHandler *handler = new CoreAuthHandler(socket, this);
+        auto *handler = new CoreAuthHandler(socket, this);
         _connectingClients.insert(handler);
 
-        connect(handler, SIGNAL(disconnected()), SLOT(clientDisconnected()));
-        connect(handler, SIGNAL(socketError(QAbstractSocket::SocketError,QString)), SLOT(socketError(QAbstractSocket::SocketError,QString)));
-        connect(handler, SIGNAL(handshakeComplete(RemotePeer*,UserId)), SLOT(setupClientSession(RemotePeer*,UserId)));
+        connect(handler, &AuthHandler::disconnected, this, &Core::clientDisconnected);
+        connect(handler, &AuthHandler::socketError, this, &Core::socketError);
+        connect(handler, &CoreAuthHandler::handshakeComplete, this, &Core::setupClientSession);
 
         quInfo() << qPrintable(tr("Client connected from"))  << qPrintable(socket->peerAddress().toString());
 
@@ -744,7 +760,7 @@ void Core::incomingConnection()
 // Potentially called during the initialization phase (before handing the connection off to the session)
 void Core::clientDisconnected()
 {
-    CoreAuthHandler *handler = qobject_cast<CoreAuthHandler *>(sender());
+    auto *handler = qobject_cast<CoreAuthHandler *>(sender());
     Q_ASSERT(handler);
 
     quInfo() << qPrintable(tr("Non-authed client disconnected:")) << qPrintable(handler->socket()->peerAddress().toString());
@@ -763,11 +779,11 @@ void Core::clientDisconnected()
 
 void Core::setupClientSession(RemotePeer *peer, UserId uid)
 {
-    CoreAuthHandler *handler = qobject_cast<CoreAuthHandler *>(sender());
+    auto *handler = qobject_cast<CoreAuthHandler *>(sender());
     Q_ASSERT(handler);
 
     // From now on everything is handled by the client session
-    disconnect(handler, 0, this, 0);
+    disconnect(handler, nullptr, this, nullptr);
     _connectingClients.remove(handler);
     handler->deleteLater();
 
@@ -783,7 +799,7 @@ void Core::setupClientSession(RemotePeer *peer, UserId uid)
 void Core::customEvent(QEvent *event)
 {
     if (event->type() == AddClientEventId) {
-        AddClientEvent *addClientEvent = static_cast<AddClientEvent *>(event);
+        auto *addClientEvent = static_cast<AddClientEvent *>(event);
         addClientHelper(addClientEvent->peer, addClientEvent->userId);
         return;
     }
@@ -835,7 +851,7 @@ void Core::setupInternalClientSession(QPointer<InternalPeer> clientPeer)
         return;
     }
 
-    InternalPeer *corePeer = new InternalPeer(this);
+    auto *corePeer = new InternalPeer(this);
     corePeer->setPeer(clientPeer);
     clientPeer->setPeer(corePeer);
 
@@ -850,10 +866,7 @@ SessionThread *Core::sessionForUser(UserId uid, bool restore)
     if (_sessions.contains(uid))
         return _sessions[uid];
 
-    SessionThread *session = new SessionThread(uid, restore, strictIdentEnabled(), this);
-    _sessions[uid] = session;
-    session->start();
-    return session;
+    return (_sessions[uid] = new SessionThread(uid, restore, strictIdentEnabled(), this));
 }
 
 
@@ -1168,7 +1181,7 @@ std::unique_ptr<AbstractSqlMigrationReader> Core::getMigrationReader(Storage *st
     if (!storage)
         return nullptr;
 
-    AbstractSqlStorage *sqlStorage = qobject_cast<AbstractSqlStorage *>(storage);
+    auto *sqlStorage = qobject_cast<AbstractSqlStorage *>(storage);
     if (!sqlStorage) {
         qDebug() << "Core::migrateDb(): only SQL based backends can be migrated!";
         return nullptr;
@@ -1183,7 +1196,7 @@ std::unique_ptr<AbstractSqlMigrationWriter> Core::getMigrationWriter(Storage *st
     if (!storage)
         return nullptr;
 
-    AbstractSqlStorage *sqlStorage = qobject_cast<AbstractSqlStorage *>(storage);
+    auto *sqlStorage = qobject_cast<AbstractSqlStorage *>(storage);
     if (!sqlStorage) {
         qDebug() << "Core::migrateDb(): only SQL based backends can be migrated!";
         return nullptr;