From 1cad7d10240a398c11af0043720d675e631f016f Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Thu, 29 Nov 2007 15:34:14 +0000 Subject: [PATCH 1/1] This should fix a bug resulting in a crash, when a IrcUser object was not destroyed before recreated. --- src/common/ircchannel.cpp | 3 +++ src/common/ircuser.cpp | 1 + src/common/networkinfo.cpp | 25 ++++++++++++++++++------- src/common/networkinfo.h | 6 ++++-- src/common/signalproxy.cpp | 5 +++-- src/core/ircserverhandler.cpp | 7 ++++--- 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/common/ircchannel.cpp b/src/common/ircchannel.cpp index cff2e751..499e1f75 100644 --- a/src/common/ircchannel.cpp +++ b/src/common/ircchannel.cpp @@ -112,6 +112,7 @@ void IrcChannel::join(IrcUser *ircuser) { if(!_userModes.contains(ircuser) && ircuser) { _userModes[ircuser] = QString(); ircuser->joinChannel(name()); + qDebug() << "JOIN" << name() << ircuser->nick() << ircUsers().count(); connect(ircuser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickSet(QString))); connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed())); // if you wonder why there is no counterpart to ircUserJoined: @@ -128,6 +129,7 @@ void IrcChannel::part(IrcUser *ircuser) { if(isKnownUser(ircuser)) { _userModes.remove(ircuser); ircuser->partChannel(name()); + qDebug() << "PART" << name() << ircuser->nick() << ircUsers().count(); // if you wonder why there is no counterpart to ircUserParted: // the joines are propagted by the ircuser. the signal ircUserParted is only for convenience emit ircUserParted(ircuser); @@ -209,6 +211,7 @@ void IrcChannel::ircUserDestroyed() { Q_ASSERT(ircUser); _userModes.remove(ircUser); emit ircUserParted(ircUser); + qDebug() << "DEST" << name() << ircUsers().count(); } void IrcChannel::ircUserNickSet(QString nick) { diff --git a/src/common/ircuser.cpp b/src/common/ircuser.cpp index fb257495..8738521b 100644 --- a/src/common/ircuser.cpp +++ b/src/common/ircuser.cpp @@ -39,6 +39,7 @@ IrcUser::IrcUser(const QString &hostmask, NetworkInfo *networkinfo) } IrcUser::~IrcUser() { + qDebug() << nick() << "destroyed."; } // ==================== diff --git a/src/common/networkinfo.cpp b/src/common/networkinfo.cpp index 0ef2f1f6..a6e311a3 100644 --- a/src/common/networkinfo.cpp +++ b/src/common/networkinfo.cpp @@ -166,6 +166,7 @@ IrcUser *NetworkInfo::newIrcUser(const QString &hostmask) { QString nick(nickFromMask(hostmask)); if(!_ircUsers.contains(nick)) { IrcUser *ircuser = new IrcUser(hostmask, this); + qDebug() << "new IrcUser()" << ircuser << hostmask; // mark IrcUser as already initialized to keep the SignalProxy from requesting initData if(initialized()) ircuser->setInitialized(); @@ -183,12 +184,20 @@ IrcUser *NetworkInfo::newIrcUser(const QString &hostmask) { return _ircUsers[nick]; } +void NetworkInfo::removeIrcUser(IrcUser *ircuser) { + QString nick = _ircUsers.key(ircuser); + if(nick.isNull()) + return; + + _ircUsers.remove(nick); + ircuser->deleteLater(); + emit ircUserRemoved(nick); +} + void NetworkInfo::removeIrcUser(QString nick) { IrcUser *ircuser; - if((ircuser = ircUser(nick)) != 0) { - ircuser->deleteLater(); - emit ircUserRemoved(nick); - } + if((ircuser = ircUser(nick)) != 0) + removeIrcUser(ircuser); } IrcUser *NetworkInfo::ircUser(const QString &nickname) const { @@ -315,10 +324,13 @@ IrcUser *NetworkInfo::updateNickFromMask(const QString &mask) { QString nick(nickFromMask(mask)); IrcUser *ircuser; + qDebug() << "NetworkInfo::updateNickFromMask()" << mask; if(_ircUsers.contains(nick)) { + qDebug() << " is known User"; ircuser = _ircUsers[nick]; ircuser->updateHostmask(mask); } else { + qDebug() << " is new User"; ircuser = newIrcUser(mask); } return ircuser; @@ -339,9 +351,8 @@ void NetworkInfo::ircUserNickChanged(QString newnick) { void NetworkInfo::ircUserDestroyed() { IrcUser *ircuser = static_cast(sender()); Q_ASSERT(ircuser); - QString nick = _ircUsers.key(ircuser); - _ircUsers.remove(nick); - emit ircUserRemoved(nick); + qDebug() << "NetworkInfo::ircUserDestroyed()" << ircuser; + removeIrcUser(ircuser); } void NetworkInfo::channelDestroyed() { diff --git a/src/common/networkinfo.h b/src/common/networkinfo.h index f767603d..a4577302 100644 --- a/src/common/networkinfo.h +++ b/src/common/networkinfo.h @@ -106,11 +106,12 @@ public slots: // these slots are to keep the hashlists of all users and the // channel lists up to date void ircUserNickChanged(QString newnick); + void setInitialized(); +private slots: void ircUserDestroyed(); void channelDestroyed(); - - void setInitialized(); + void removeIrcUser(IrcUser *ircuser); signals: void networkNameSet(const QString &networkName); @@ -149,6 +150,7 @@ private: QPointer _proxy; void determinePrefixes(); + }; #endif diff --git a/src/common/signalproxy.cpp b/src/common/signalproxy.cpp index 904768d5..a5c41cc8 100644 --- a/src/common/signalproxy.cpp +++ b/src/common/signalproxy.cpp @@ -583,7 +583,7 @@ void SignalProxy::handleInitRequest(QIODevice *sender, const QVariantList ¶m QByteArray className(params[0].toByteArray()); QString objectName(params[1].toString()); - + if(!_syncSlave.contains(className)) { qWarning() << "SignalProxy::handleInitRequest() received initRequest for unregistered Class:" << className; @@ -595,8 +595,9 @@ void SignalProxy::handleInitRequest(QIODevice *sender, const QVariantList ¶m << className << objectName; return; } - + QObject *obj = _syncSlave[className][objectName]; + qDebug() << "Receive Init Request for" << className << objectName << obj; QVariantList params_; params_ << obj->metaObject()->className() diff --git a/src/core/ircserverhandler.cpp b/src/core/ircserverhandler.cpp index 21430500..d83e4209 100644 --- a/src/core/ircserverhandler.cpp +++ b/src/core/ircserverhandler.cpp @@ -153,7 +153,7 @@ void IrcServerHandler::handleJoin(QString prefix, QStringList params) { QString channel = params[0]; IrcUser *ircuser = networkInfo()->updateNickFromMask(prefix); emit displayMsg(Message::Join, channel, channel, prefix); - + qDebug() << "IrcServerHandler::handleJoin()" << prefix << params; ircuser->joinChannel(channel); } @@ -285,6 +285,7 @@ void IrcServerHandler::handlePrivmsg(QString prefix, QStringList params) { void IrcServerHandler::handleQuit(QString prefix, QStringList params) { IrcUser *ircuser = networkInfo()->updateNickFromMask(prefix); Q_ASSERT(ircuser); + qDebug() << "IrcServerHandler:handleQuit" << prefix << params; QString msg; if(params.count()) @@ -292,8 +293,8 @@ void IrcServerHandler::handleQuit(QString prefix, QStringList params) { foreach(QString channel, ircuser->channels()) emit displayMsg(Message::Quit, channel, msg, prefix); - - ircuser->deleteLater(); + + networkInfo()->removeIrcUser(nickFromMask(prefix)); } void IrcServerHandler::handleTopic(QString prefix, QStringList params) { -- 2.20.1