[Telepathy-commits] [telepathy-qt4/master] Add a new readiness enum value, ReadinessClosed.

George Goldberg george.goldberg at collabora.co.uk
Wed Nov 5 07:28:50 PST 2008


As discussed on #telepathy with oggis, this new enum value represents the readiness state of the channel when it has been closed. It replaces the closed() signal which could cause race conditions with queued signal/slot connections. This means ReadinessDead is now only for when the channel dies unexpectedly, rather than being closed by the class user in a controlled way.
---
 TelepathyQt4/cli-channel.cpp |   30 +++++++++++++++-------------
 TelepathyQt4/cli-channel.h   |   44 ++++++++++++++++++++++-------------------
 2 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/TelepathyQt4/cli-channel.cpp b/TelepathyQt4/cli-channel.cpp
index 6c32417..dd4d94b 100644
--- a/TelepathyQt4/cli-channel.cpp
+++ b/TelepathyQt4/cli-channel.cpp
@@ -328,14 +328,15 @@ struct Channel::Private
     void changeReadiness(Readiness newReadiness)
     {
         Q_ASSERT(newReadiness != readiness);
-
+        // REVIEWME: Should we allow ReadinessJustCreated->ReadinessClosed?
         switch (readiness) {
             case ReadinessJustCreated:
                 break;
             case ReadinessFull:
-                Q_ASSERT(newReadiness == ReadinessDead);
+                Q_ASSERT((newReadiness == ReadinessDead) || (newReadiness == ReadinessClosed));
                 break;
             case ReadinessDead:
+            case ReadinessClosed:
             default:
                 Q_ASSERT(false);
                 break;
@@ -361,7 +362,7 @@ struct Channel::Private
                 debug() << " Group: Self handle" << groupSelfHandle << "tracked:" << (groupIsSelfHandleTracked ? "yes" : "no");
             }
         } else {
-            Q_ASSERT(newReadiness == ReadinessDead);
+            Q_ASSERT((newReadiness == ReadinessDead) || (newReadiness == ReadinessClosed));
 
             debug() << "R.I.P. Channel.";
 
@@ -415,6 +416,8 @@ QStringList Channel::interfaces() const
         warning() << "Channel::interfaces() used possibly before the list of interfaces has been received";
     else if (mPriv->readiness == ReadinessDead)
         warning() << "Channel::interfaces() used with readiness ReadinessDead";
+    else if (mPriv->readiness == ReadinessClosed)
+        warning() << "Channel::interfaces() used with readiness ReadinessClosed";
 
     return mPriv->interfaces;
 }
@@ -427,6 +430,8 @@ QString Channel::channelType() const
         warning() << "Channel::channelType() before the channel type has been received";
     else if (mPriv->readiness == ReadinessDead)
         warning() << "Channel::channelType() used with readiness ReadinessDead";
+    else if (mPriv->readiness == ReadinessClosed)
+        warning() << "Channel::channelType() used with readiness ReadinessClosed";
 
     return mPriv->channelType;
 }
@@ -449,8 +454,8 @@ uint Channel::targetHandle() const
 
 QDBusPendingReply<> Channel::close()
 {
-    // Closing a channel does not make sense if it is already dead.
-    if (mPriv->readiness != ReadinessDead)
+    // Closing a channel does not make sense if it is already dead or closed.
+    if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
         return mPriv->baseInterface->Close();
 
     // If the channel is in a readiness where it doesn't make sense to be
@@ -458,7 +463,7 @@ QDBusPendingReply<> Channel::close()
     warning() << "Channel::close() used with readiness" << mPriv->readiness;
 
     return QDBusPendingReply<>(QDBusMessage::createError(
-            "TELEPATHY_ERROR_NOT_AVAILABLE", "Attempted to close an already dead channel"));
+            "TELEPATHY_ERROR_NOT_AVAILABLE", "Attempted to close an already dead or closed channel"));
 }
 
 uint Channel::groupFlags() const
@@ -582,7 +587,7 @@ void Channel::gotChannelType(QDBusPendingCallWatcher* watcher)
 
     if (reply.isError()) {
         warning().nospace() << "Channel::GetChannelType() failed with " << reply.error().name() << ": " << reply.error().message() << ", Channel officially dead";
-        if (mPriv->readiness != ReadinessDead)
+        if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
             mPriv->changeReadiness(ReadinessDead);
         return;
     }
@@ -598,7 +603,7 @@ void Channel::gotHandle(QDBusPendingCallWatcher* watcher)
 
     if (reply.isError()) {
         warning().nospace() << "Channel::GetHandle() failed with " << reply.error().name() << ": " << reply.error().message() << ", Channel officially dead";
-        if (mPriv->readiness != ReadinessDead)
+        if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
             mPriv->changeReadiness(ReadinessDead);
         return;
     }
@@ -615,7 +620,7 @@ void Channel::gotInterfaces(QDBusPendingCallWatcher* watcher)
 
     if (reply.isError()) {
         warning().nospace() << "Channel::GetInterfaces() failed with " << reply.error().name() << ": " << reply.error().message() << ", Channel officially dead";
-        if (mPriv->readiness != ReadinessDead)
+        if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
             mPriv->changeReadiness(ReadinessDead);
         return;
     }
@@ -630,11 +635,8 @@ void Channel::onClosed()
 {
     debug() << "Got Channel::Closed";
 
-    if (mPriv->readiness != ReadinessDead)
-        mPriv->changeReadiness(ReadinessDead);
-
-    // Relay the channel interface's closed() signal.
-    emit closed();
+    if ((mPriv->readiness != ReadinessDead) && (mPriv->readiness != ReadinessClosed))
+        mPriv->changeReadiness(ReadinessClosed);
 }
 
 void Channel::gotGroupProperties(QDBusPendingCallWatcher* watcher)
diff --git a/TelepathyQt4/cli-channel.h b/TelepathyQt4/cli-channel.h
index 33104bb..aedbc6e 100644
--- a/TelepathyQt4/cli-channel.h
+++ b/TelepathyQt4/cli-channel.h
@@ -98,8 +98,9 @@ public:
          * The object has just been created and introspection is still in
          * progress. No functionality dependent on introspection is available.
          *
-         * The readiness can change to any other state depending on the result
-         * of the initial state query to the remote object.
+         * The readiness can change to any other state except ReadinessClosed
+         * depending on the result of the initial state query to the remote
+         * object.
          */
         ReadinessJustCreated = 0,
 
@@ -107,18 +108,26 @@ public:
          * The remote object is alive and all introspection has been completed.
          * Most functionality is available.
          *
-         * The readiness can change to ReadinessDead.
+         * The readiness can change to ReadinessDead or ReadinessClosed.
          */
         ReadinessFull = 5,
 
         /**
          * The remote object has gone into a state where it can no longer be
-         * used. No functionality is available.
+         * used in an unexpected way. No functionality is available.
          *
          * No further readiness changes are possible.
          */
         ReadinessDead = 10,
 
+        /**
+         * The remote object has been closed and so can no longer be used.
+         * No functionality is available.
+         *
+         * No further readiness changes are possible.
+         */
+        ReadinessClosed = 15,
+
         _ReadinessInvalid = 0xffff
     };
 
@@ -196,9 +205,9 @@ public Q_SLOTS:
      * use the returned object.
      *
      * A channel can be closed if its Readiness is ReadinessJustCreated or
-     * ReadinessFull. It cannot be closed if its Readiness is already
-     * ReadinessDead. If this method is called on a channel which is already
-     * in the ReadinessDead state, a DBus error of type
+     * ReadinessFull. It cannot be closed if its Readiness is ReadinessDead or
+     * ReadinessClosed. If this method is called on a channel which is already
+     * in either the ReadinessDead or ReadinessClosed state, a DBus error of type
      * TELEPATHY_ERROR_NOT_AVAILABLE will be returned.
      *
      * \return QDBusPendingReply object for the call to Close() on the Channel
@@ -208,20 +217,14 @@ public Q_SLOTS:
 
 Q_SIGNALS:
     /**
-     * Emitted whenever the readiness of the Channel changes.
+     * Emitted whenever the readiness of the Channel changes. When the channel
+     * is closed, this signal will be emitted with readiness #ReadinessClosed.
      *
      * \param newReadiness The new readiness, as defined in #Readiness.
      */
     void readinessChanged(Telepathy::Client::Channel::Readiness newReadiness);
 
     /**
-     * Emitted when the channel has been closed. Method calls on the channel
-     * are no longer valid after this signal has been emitted, and the
-     * connection manager may then remove the object from the bus at any point.
-     */
-    void closed();
-
-    /**
      * \name Group interface
      *
      * Cached access to state of the group interface on the associated remote
@@ -432,11 +435,12 @@ public:
      * GroupMemberChangeInfo::isValid() returns <code>false</code> is returned.
      *
      * This method works even when the channel has gone into readiness
-     * #ReadinessDead. This is useful for getting the remove information after
-     * missing the corresponding groupMembersChanged() (or
-     * groupLocalPendingChanged()/groupRemotePendingChanged()) signal, as the
-     * local user being removed usually causes the remote %Channel to be closed,
-     * and consequently the Channel object going into that readiness state.
+     * #ReadinessDead or #ReadinessClosed. This is useful for getting the
+     * remove information after missing the corresponding groupMembersChanged()
+     * (or groupLocalPendingChanged()/groupRemotePendingChanged()) signal, as
+     * the local user being removed usually causes the remote %Channel to be
+     * closed, and consequently the Channel object going into that readiness
+     * state.
      *
      * The returned information is not guaranteed to be correct if
      * groupIsSelfHandleTracked() returns false and a self handle change has
-- 
1.5.6.5




More information about the Telepathy-commits mailing list