#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
// ==============================
// 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
Core::~Core()
{
- saveState();
qDeleteAll(_connectingClients);
qDeleteAll(_sessions);
syncStorage();
- _instance = nullptr;
}
{
_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;
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!")};
}
+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()
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) {
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);
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;
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;
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());
// 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());
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();
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;
}
return;
}
- InternalPeer *corePeer = new InternalPeer(this);
+ auto *corePeer = new InternalPeer(this);
corePeer->setPeer(clientPeer);
clientPeer->setPeer(corePeer);
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));
}
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;
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;