X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcore%2Fcorenetwork.cpp;h=c02338532a5c5e845aad70f7a43c0e39c49e9018;hp=b9e82e44a4710e2147d55bc36c7ac710d000a930;hb=f4693532403c2bcba592d322d0b5dbceaf76e758;hpb=841df8c7cc71ff1b8099d49296c8e997c92bdd60 diff --git a/src/core/corenetwork.cpp b/src/core/corenetwork.cpp index b9e82e44..c0233853 100644 --- a/src/core/corenetwork.cpp +++ b/src/core/corenetwork.cpp @@ -40,6 +40,8 @@ CoreNetwork::CoreNetwork(const NetworkId &networkid, CoreSession *session) _previousConnectionAttemptFailed(false), _lastUsedServerIndex(0), + _lastPingTime(0), + // TODO make autowho configurable (possibly per-network) _autoWhoEnabled(true), _autoWhoInterval(90), @@ -50,7 +52,7 @@ CoreNetwork::CoreNetwork(const NetworkId &networkid, CoreSession *session) _socketCloseTimer.setSingleShot(true); connect(&_socketCloseTimer, SIGNAL(timeout()), this, SLOT(socketCloseTimeout())); - _pingTimer.setInterval(60000); + _pingTimer.setInterval(30000); connect(&_pingTimer, SIGNAL(timeout()), this, SLOT(sendPing())); _autoWhoTimer.setInterval(_autoWhoDelay * 1000); @@ -181,10 +183,13 @@ void CoreNetwork::connectToIrc(bool reconnecting) { #endif } -void CoreNetwork::disconnectFromIrc(bool requested, const QString &reason) { +void CoreNetwork::disconnectFromIrc(bool requested, const QString &reason, bool withReconnect) { _quitRequested = requested; // see socketDisconnected(); - _autoReconnectTimer.stop(); - _autoReconnectCount = 0; // prohibiting auto reconnect + if(!withReconnect) { + _autoReconnectTimer.stop(); + _autoReconnectCount = 0; // prohibiting auto reconnect + } + disablePingTimeout(); IrcUser *me_ = me(); if(me_) { @@ -195,24 +200,23 @@ void CoreNetwork::disconnectFromIrc(bool requested, const QString &reason) { Core::setUserModes(userId(), networkId(), me_->userModes()); } - displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Disconnecting.")); - if(socket.state() == QAbstractSocket::UnconnectedState) { - socketDisconnected(); - } else if(socket.state() < QAbstractSocket::ConnectedState || !requested) { - // we might be in a state waiting for a timeout... - // or (!requested) this is a core shutdown... - // in both cases we don't really care... set a disconnected state + if(reason.isEmpty() && identityPtr()) + _quitReason = identityPtr()->quitReason(); + else + _quitReason = reason; + + displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Disconnecting. (%1)").arg((!requested && !withReconnect) ? tr("Core Shutdown") : reason)); + switch(socket.state()) { + case QAbstractSocket::ConnectedState: + userInputHandler()->issueQuit(_quitReason); + if(requested || withReconnect) { + // the irc server has 10 seconds to close the socket + _socketCloseTimer.start(10000); + break; + } + default: socket.close(); socketDisconnected(); - } else { - // quit gracefully if it's user requested quit - if(reason.isEmpty() && identityPtr()) - _quitReason = identityPtr()->quitReason(); - else - _quitReason = reason; - userInputHandler()->issueQuit(_quitReason); - // the irc server has 10 seconds to close the socket - _socketCloseTimer.start(10000); } } @@ -332,7 +336,8 @@ void CoreNetwork::socketInitialized() { } void CoreNetwork::socketDisconnected() { - _pingTimer.stop(); + disablePingTimeout(); + _autoWhoCycleTimer.stop(); _autoWhoTimer.stop(); _autoWhoQueue.clear(); @@ -395,7 +400,9 @@ void CoreNetwork::networkInitialized() { } // restore away state - userInputHandler()->handleAway(BufferInfo(), Core::awayMessage(userId(), networkId())); + QString awayMsg = Core::awayMessage(userId(), networkId()); + if(!awayMsg.isEmpty()) + userInputHandler()->handleAway(BufferInfo(), Core::awayMessage(userId(), networkId())); // restore old user modes if server default mode is set. IrcUser *me_ = me(); @@ -410,7 +417,7 @@ void CoreNetwork::networkInitialized() { sendPerform(); - _pingTimer.start(); + enablePingTimeout(); if(_autoWhoEnabled) { _autoWhoCycleTimer.start(); @@ -506,7 +513,26 @@ void CoreNetwork::doAutoReconnect() { } void CoreNetwork::sendPing() { - userInputHandler()->handlePing(BufferInfo(), QString()); + uint now = QDateTime::currentDateTime().toTime_t(); + if(_lastPingTime != 0 && now - _lastPingTime <= (uint)(_pingTimer.interval() / 1000) + 1) { + // the second check compares the actual elapsed time since the last ping and the pingTimer interval + // if the interval is shorter then the actual elapsed time it means that this thread was somehow blocked + // and unable to even handle a ping answer. So we ignore those misses. + disconnectFromIrc(false, QString("No Ping reply in %1 seconds.").arg(_pingTimer.interval() / 1000), true /* withReconnect */); + } else { + _lastPingTime = now; + userInputHandler()->handlePing(BufferInfo(), QString()); + } +} + +void CoreNetwork::enablePingTimeout() { + resetPingTimeout(); + _pingTimer.start(); +} + +void CoreNetwork::disablePingTimeout() { + _pingTimer.stop(); + resetPingTimeout(); } void CoreNetwork::sendAutoWho() {