summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Moreira Magalhaes (andrunko) <andre.magalhaes@collabora.co.uk>2010-12-31 11:22:31 -0200
committerAndre Moreira Magalhaes (andrunko) <andre.magalhaes@collabora.co.uk>2010-12-31 11:22:35 -0200
commit58a450dad4c5706fa73282f01b6511cbd0f749a8 (patch)
tree0f9e6743d9f0543ceb95bda25b84d5d2c65343ff
parent994a3c140969fab694288e9252dc31bcf09f73f9 (diff)
parent5162f291c8c4df953286868abec7ad8876d9f543 (diff)
Merge branch 'conn-roster-leak'
Reviewed-by: Olli Salli (oggis) <olli.salli@collabora.co.uk>
-rw-r--r--TelepathyQt4/connection-internal.h2
-rw-r--r--TelepathyQt4/connection.cpp20
-rw-r--r--TelepathyQt4/contact-manager.cpp14
-rw-r--r--TelepathyQt4/contact-manager.h2
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;