X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fcore%2Fcoresession.cpp;h=49898b297169759bfc1dfca77bab6d6dee8cd3da;hb=156f88b0a12dd2fb65a78c3ce088ce6ba57feafe;hp=112aa8564d8775feb96405bfa15693379d1a0b72;hpb=921e54680da16fcf2adb7a90506875aceb6633a4;p=quassel.git diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index 112aa856..49898b29 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2015 by the Quassel Project * + * Copyright (C) 2005-2016 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -100,6 +100,9 @@ CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent) p->attachSlot(SIGNAL(createNetwork(const NetworkInfo &, const QStringList &)), this, SLOT(createNetwork(const NetworkInfo &, const QStringList &))); p->attachSlot(SIGNAL(removeNetwork(NetworkId)), this, SLOT(removeNetwork(NetworkId))); + p->attachSlot(SIGNAL(changePassword(PeerPtr,QString,QString,QString)), this, SLOT(changePassword(PeerPtr,QString,QString,QString))); + p->attachSignal(this, SIGNAL(passwordChanged(PeerPtr,bool))); + loadSettings(); initScriptEngine(); @@ -134,7 +137,47 @@ CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent) CoreSession::~CoreSession() { saveSessionState(); + + /* Why partially duplicate CoreNetwork destructor? When each CoreNetwork quits in the + * destructor, disconnections are processed in sequence for each object. For many IRC servers + * on a slow network, this could significantly delay core shutdown [msecs wait * network count]. + * + * Here, CoreSession first calls disconnect on all networks, letting them all start + * disconnecting before beginning to sequentially wait for each network. Ideally, after the + * first network is disconnected, the other networks will have already closed. Worst-case may + * still wait [msecs wait time * num. of networks], but the risk should be much lower. + * + * CoreNetwork should still do cleanup in its own destructor in case a network is deleted + * outside of deleting the whole CoreSession. + * + * If this proves to be problematic in the future, there's an alternative Qt signal-based system + * implemented in another pull request that guarentees a maximum amount of time to disconnect, + * but at the cost of more complex code. + * + * See https://github.com/quassel/quassel/pull/203 + */ + foreach(CoreNetwork *net, _networks.values()) { + // Request each network properly disconnect, but don't count as user-requested disconnect + if (net->socketConnected()) { + // Only try if the socket's fully connected (not initializing or disconnecting). + // Force an immediate disconnect, jumping the command queue. Ensures the proper QUIT is + // shown even if other messages are queued. + net->disconnectFromIrc(false, QString(), false, true); + } + } + + // Process the putCmd events that trigger the quit. Without this, shutting down the core + // results in abrubtly closing the socket rather than sending the QUIT as expected. + QCoreApplication::processEvents(); + + foreach(CoreNetwork *net, _networks.values()) { + // Wait briefly for each network to disconnect. Sometimes it takes a little while to send. + if (!net->forceDisconnect()) { + qWarning() << "Timed out quitting network" << net->networkName() << + "(user ID " << net->userId() << ")"; + } + // Delete the network now that it's closed delete net; } } @@ -172,7 +215,7 @@ void CoreSession::loadSettings() networkIter = networkInfos.erase(networkIter); } else { - networkIter++; + ++networkIter; } } s.removeIdentity(id); @@ -545,7 +588,7 @@ void CoreSession::destroyNetwork(NetworkId id) messageIter = _messageQueue.erase(messageIter); } else { - messageIter++; + ++messageIter; } } // remove buffers from syncer @@ -575,7 +618,7 @@ void CoreSession::clientsConnected() IrcUser *me = 0; while (netIter != _networks.end()) { net = *netIter; - netIter++; + ++netIter; if (!net->isConnected()) continue; @@ -602,7 +645,7 @@ void CoreSession::clientsDisconnected() QString awayReason; while (netIter != _networks.end()) { net = *netIter; - netIter++; + ++netIter; if (!net->isConnected()) continue; @@ -630,7 +673,7 @@ void CoreSession::globalAway(const QString &msg) CoreNetwork *net = 0; while (netIter != _networks.end()) { net = *netIter; - netIter++; + ++netIter; if (!net->isConnected()) continue; @@ -638,3 +681,13 @@ void CoreSession::globalAway(const QString &msg) net->userInputHandler()->issueAway(msg, false /* no force away */); } } + +void CoreSession::changePassword(PeerPtr peer, const QString &userName, const QString &oldPassword, const QString &newPassword) +{ + bool success = false; + UserId uid = Core::validateUser(userName, oldPassword); + if (uid.isValid() && uid == user()) + success = Core::changeUserPassword(uid, newPassword); + + emit passwordChanged(peer, success); +}