[telepathy-qt4/master] ReadinessHelper: Be more defensive regarding PendingOperations finish/destroy.

Andre Moreira Magalhaes (andrunko) andre.magalhaes at collabora.co.uk
Tue Mar 31 19:27:52 PDT 2009


---
 TelepathyQt4/Client/connection.cpp       |    2 +-
 TelepathyQt4/Client/pending-ready.cpp    |    4 +-
 TelepathyQt4/Client/pending-ready.h      |    3 +-
 TelepathyQt4/Client/readiness-helper.cpp |   38 +++++++++++++++++++++++++----
 TelepathyQt4/Client/readiness-helper.h   |    3 ++
 5 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/TelepathyQt4/Client/connection.cpp b/TelepathyQt4/Client/connection.cpp
index 64cfdfb..7449ba7 100644
--- a/TelepathyQt4/Client/connection.cpp
+++ b/TelepathyQt4/Client/connection.cpp
@@ -390,7 +390,7 @@ void Connection::Private::introspectRoster(Connection::Private *self)
 }
 
 Connection::PendingConnect::PendingConnect(Connection *parent, const Features &requestedFeatures)
-    : PendingReady(requestedFeatures, parent)
+    : PendingReady(requestedFeatures, parent, parent)
 {
     QDBusPendingCall call = parent->baseInterface()->Connect();
     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, parent);
diff --git a/TelepathyQt4/Client/pending-ready.cpp b/TelepathyQt4/Client/pending-ready.cpp
index 9729d95..11ac046 100644
--- a/TelepathyQt4/Client/pending-ready.cpp
+++ b/TelepathyQt4/Client/pending-ready.cpp
@@ -68,8 +68,8 @@ struct PendingReady::Private
  * \param object The object that will become ready.
  */
 PendingReady::PendingReady(const Features &requestedFeatures,
-        QObject *object)
-    : PendingOperation(object),
+        QObject *object, QObject *parent)
+    : PendingOperation(parent),
       mPriv(new Private(requestedFeatures, object))
 {
 }
diff --git a/TelepathyQt4/Client/pending-ready.h b/TelepathyQt4/Client/pending-ready.h
index 1e25a62..a018959 100644
--- a/TelepathyQt4/Client/pending-ready.h
+++ b/TelepathyQt4/Client/pending-ready.h
@@ -41,7 +41,8 @@ class PendingReady: public PendingOperation
     Q_OBJECT
 
 public:
-    PendingReady(const Features &requestedFeatures, QObject *object);
+    PendingReady(const Features &requestedFeatures, QObject *object,
+            QObject *parent = 0);
     ~PendingReady();
 
     QObject *object() const;
diff --git a/TelepathyQt4/Client/readiness-helper.cpp b/TelepathyQt4/Client/readiness-helper.cpp
index dd06be2..f7e415d 100644
--- a/TelepathyQt4/Client/readiness-helper.cpp
+++ b/TelepathyQt4/Client/readiness-helper.cpp
@@ -217,7 +217,6 @@ void ReadinessHelper::Private::iterateIntrospection()
             } else {
                 operation->setFinishedWithError(errorName, errorMessage);
             }
-            pendingOperations.removeOne(operation);
         }
     }
 
@@ -283,9 +282,17 @@ void ReadinessHelper::Private::abortOperations(const QString &errorName,
         const QString &errorMessage)
 {
     foreach (PendingReady *operation, pendingOperations) {
+        parent->disconnect(operation,
+                SIGNAL(finished(Telepathy::Client::PendingOperation*)),
+                parent,
+                SLOT(onOperationFinished(Telepathy::Client::PendingOperation*)));
+        parent->disconnect(operation,
+                SIGNAL(destroyed(QObject*)),
+                parent,
+                SLOT(onOperationDestroyed(QObject*)));
         operation->setFinishedWithError(errorName, errorMessage);
-        pendingOperations.removeOne(operation);
     }
+    pendingOperations.clear();
 }
 
 ReadinessHelper::ReadinessHelper(QObject *object,
@@ -445,7 +452,7 @@ PendingReady *ReadinessHelper::becomeReady(const Features &requestedFeatures)
         debug() << "ReadinessHelper::becomeReady called with invalid features: requestedFeatures =" <<
             requestedFeatures << "- supportedFeatures =" << mPriv->supportedFeatures;
         PendingReady *operation =
-            new PendingReady(requestedFeatures, mPriv->object);
+            new PendingReady(requestedFeatures, mPriv->object, this);
         operation->setFinishedWithError(
                 QLatin1String(TELEPATHY_ERROR_INVALID_ARGUMENT),
                 QLatin1String("Requested features contains unsupported feature"));
@@ -454,7 +461,7 @@ PendingReady *ReadinessHelper::becomeReady(const Features &requestedFeatures)
 
     if (mPriv->proxy && !mPriv->proxy->isValid()) {
         PendingReady *operation =
-            new PendingReady(requestedFeatures, mPriv->object);
+            new PendingReady(requestedFeatures, mPriv->object, this);
         operation->setFinishedWithError(mPriv->proxy->invalidationReason(),
                 mPriv->proxy->invalidationMessage());
         return operation;
@@ -471,7 +478,13 @@ PendingReady *ReadinessHelper::becomeReady(const Features &requestedFeatures)
     // it will be updated on iterateIntrospection
     mPriv->pendingFeatures += requestedFeatures;
 
-    operation = new PendingReady(requestedFeatures, mPriv->object);
+    operation = new PendingReady(requestedFeatures, mPriv->object, this);
+    connect(operation,
+            SIGNAL(finished(Telepathy::Client::PendingOperation*)),
+            SLOT(onOperationFinished(Telepathy::Client::PendingOperation*)));
+    connect(operation,
+            SIGNAL(destroyed(QObject*)),
+            SLOT(onOperationDestroyed(QObject*)));
     mPriv->pendingOperations.append(operation);
 
     QTimer::singleShot(0, this, SLOT(iterateIntrospection()));
@@ -500,7 +513,7 @@ void ReadinessHelper::iterateIntrospection()
     mPriv->iterateIntrospection();
 }
 
-void ReadinessHelper::onProxyInvalidated(Telepathy::Client::DBusProxy *proxy,
+void ReadinessHelper::onProxyInvalidated(DBusProxy *proxy,
         const QString &errorName, const QString &errorMessage)
 {
     // clear satisfied and missing features as we have public methods to get them
@@ -510,5 +523,18 @@ void ReadinessHelper::onProxyInvalidated(Telepathy::Client::DBusProxy *proxy,
     mPriv->abortOperations(errorName, errorMessage);
 }
 
+void ReadinessHelper::onOperationFinished(PendingOperation *op)
+{
+    disconnect(op,
+               SIGNAL(destroyed(QObject*)),
+               this,
+               SLOT(onOperationDestroyed(QObject*)));
+    mPriv->pendingOperations.removeOne(qobject_cast<PendingReady*>(op));
+}
+
+void ReadinessHelper::onOperationDestroyed(QObject *obj)
+{
+    mPriv->pendingOperations.removeOne(qobject_cast<PendingReady*>(obj));
+}
 }
 }
diff --git a/TelepathyQt4/Client/readiness-helper.h b/TelepathyQt4/Client/readiness-helper.h
index 51db440..01e62f2 100644
--- a/TelepathyQt4/Client/readiness-helper.h
+++ b/TelepathyQt4/Client/readiness-helper.h
@@ -40,6 +40,7 @@ namespace Client
 {
 
 class DBusProxy;
+class PendingOperation;
 class PendingReady;
 
 class ReadinessHelper : public QObject
@@ -122,6 +123,8 @@ private Q_SLOTS:
 
     void onProxyInvalidated(Telepathy::Client::DBusProxy *proxy,
         const QString &errorName, const QString &errorMessage);
+    void onOperationFinished(Telepathy::Client::PendingOperation *op);
+    void onOperationDestroyed(QObject *obj);
 
 private:
     struct Private;
-- 
1.5.6.5




More information about the telepathy-commits mailing list