diff options
author | Andre Moreira Magalhaes (andrunko) <andre.magalhaes@collabora.co.uk> | 2010-12-31 11:22:31 -0200 |
---|---|---|
committer | Andre Moreira Magalhaes (andrunko) <andre.magalhaes@collabora.co.uk> | 2010-12-31 11:22:35 -0200 |
commit | 58a450dad4c5706fa73282f01b6511cbd0f749a8 (patch) | |
tree | 0f9e6743d9f0543ceb95bda25b84d5d2c65343ff | |
parent | 994a3c140969fab694288e9252dc31bcf09f73f9 (diff) | |
parent | 5162f291c8c4df953286868abec7ad8876d9f543 (diff) |
Merge branch 'conn-roster-leak'
Reviewed-by: Olli Salli (oggis) <olli.salli@collabora.co.uk>
-rw-r--r-- | TelepathyQt4/connection-internal.h | 2 | ||||
-rw-r--r-- | TelepathyQt4/connection.cpp | 20 | ||||
-rw-r--r-- | TelepathyQt4/contact-manager.cpp | 14 | ||||
-rw-r--r-- | TelepathyQt4/contact-manager.h | 2 |
4 files changed, 35 insertions, 3 deletions
diff --git a/TelepathyQt4/connection-internal.h b/TelepathyQt4/connection-internal.h index 6e30ce83..617fe261 100644 --- a/TelepathyQt4/connection-internal.h +++ b/TelepathyQt4/connection-internal.h @@ -46,8 +46,6 @@ private Q_SLOTS: private: friend class ConnectionLowlevel; - - ConnectionPtr connection; }; class ConnectionHelper diff --git a/TelepathyQt4/connection.cpp b/TelepathyQt4/connection.cpp index b7fde4ba..2d0fda54 100644 --- a/TelepathyQt4/connection.cpp +++ b/TelepathyQt4/connection.cpp @@ -327,6 +327,8 @@ Connection::Private::Private(Connection *parent, Connection::Private::~Private() { + contactManager->resetContactListChannels(); + // Clear selfContact so its handle will be released cleanly before the // handleContext selfContact.reset(); @@ -740,7 +742,7 @@ ConnectionPtr ConnectionLowlevel::connection() const Connection::PendingConnect::PendingConnect(const ConnectionPtr &connection, const Features &requestedFeatures) - : PendingReady(connection, requestedFeatures), connection(connection) + : PendingReady(connection, requestedFeatures) { if (!connection) { // Called when the connection had already been destroyed @@ -817,6 +819,8 @@ void Connection::PendingConnect::onStatusChanged(ConnectionStatus newStatus) void Connection::PendingConnect::onBecomeReadyReply(Tp::PendingOperation *op) { + ConnectionPtr connection = ConnectionPtr::qObjectCast(proxy()); + // We don't care about future disconnects even if they happen before we are destroyed // (which happens two mainloop iterations from now) connection->disconnect(this, @@ -843,6 +847,8 @@ void Connection::PendingConnect::onBecomeReadyReply(Tp::PendingOperation *op) void Connection::PendingConnect::onConnInvalidated(Tp::DBusProxy *proxy, const QString &error, const QString &message) { + ConnectionPtr connection = ConnectionPtr::qObjectCast(this->proxy()); + Q_ASSERT(proxy == connection.data()); if (!isFinished()) { @@ -1462,6 +1468,10 @@ void Connection::onStatusReady(uint status) { Q_ASSERT(status == mPriv->pendingStatus); + if (mPriv->status == status) { + return; + } + mPriv->status = status; mPriv->statusReason = mPriv->pendingStatusReason; @@ -1898,6 +1908,10 @@ void Connection::gotContactListChannel(PendingOperation *op) mPriv->contactListChannels[i].handle[0] == handle) { Q_ASSERT(!mPriv->contactListChannels[i].channel); mPriv->contactListChannels[i].channel = channel; + // deref connection refcount here as connection will keep a ref to channel and we don't + // want a contact list channel keeping a ref of connection, otherwise connection will + // leak, thus the channels. + channel->connection()->deref(); connect(channel->becomeReady(), SIGNAL(finished(Tp::PendingOperation*)), SLOT(contactListChannelReady())); @@ -1938,6 +1952,10 @@ void Connection::onNewChannels(const Tp::ChannelDetailsList &channelDetailsList) ChannelPtr channel = Channel::create(ConnectionPtr(this), channelDetails.channel.path(), channelDetails.properties); mPriv->contactListGroupChannels.append(channel); + // deref connection refcount here as connection will keep a ref to channel and we don't + // want a contact list group channel keeping a ref of connection, otherwise connection will + // leak, thus the channels. + channel->connection()->deref(); connect(channel->becomeReady(), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onContactListGroupChannelReady(Tp::PendingOperation*))); diff --git a/TelepathyQt4/contact-manager.cpp b/TelepathyQt4/contact-manager.cpp index d49d9415..fb5c4b62 100644 --- a/TelepathyQt4/contact-manager.cpp +++ b/TelepathyQt4/contact-manager.cpp @@ -132,6 +132,7 @@ struct TELEPATHY_QT4_NO_EXPORT ContactManager::Private ChannelPtr storedChannel; ChannelPtr denyChannel; QMap<QString, ChannelPtr> contactListGroupChannels; + QList<ChannelPtr> removedContactListGroupChannels; // avatar UIntList requestAvatarsQueue; @@ -2098,6 +2099,8 @@ void ContactManager::onContactListGroupRemovedFallback(Tp::DBusProxy *proxy, QString id = contactListGroupChannel->immutableProperties().value( QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".TargetID")).toString(); mPriv->contactListGroupChannels.remove(id); + mPriv->removedContactListGroupChannels.append(contactListGroupChannel); + disconnect(contactListGroupChannel.data(), 0, 0, 0); emit groupRemoved(id); } @@ -2276,6 +2279,17 @@ void ContactManager::addContactListGroupChannelFallback( emit groupAdded(id); } +void ContactManager::resetContactListChannels() +{ + mPriv->contactListChannels.clear(); + mPriv->subscribeChannel.reset(); + mPriv->publishChannel.reset(); + mPriv->storedChannel.reset(); + mPriv->denyChannel.reset(); + mPriv->contactListGroupChannels.clear(); + mPriv->removedContactListGroupChannels.clear(); +} + QString ContactManager::featureToInterface(const Feature &feature) { if (feature == Contact::FeatureAlias) { diff --git a/TelepathyQt4/contact-manager.h b/TelepathyQt4/contact-manager.h index a676c386..75d3cb63 100644 --- a/TelepathyQt4/contact-manager.h +++ b/TelepathyQt4/contact-manager.h @@ -248,6 +248,8 @@ private: void addContactListGroupChannelFallback( const ChannelPtr &contactListGroupChannel); + void resetContactListChannels(); + static QString featureToInterface(const Feature &feature); struct Private; |