dbus/qt qdbusabstractinterface.cpp, 1.2, 1.3 qdbusabstractinterface.h, 1.2, 1.3 qdbusbus.h, 1.1, 1.2 qdbusconnection.h, 1.6, 1.7 qdbusconnection_p.h, 1.8, 1.9 qdbusintegrator.cpp, 1.9, 1.10 qdbusinterface.cpp, 1.5, 1.6 qdbusinterface.h, 1.4, 1.5 qdbusinterface_p.h, 1.4, 1.5 qdbusinternalfilters.cpp, 1.4, 1.5

Thiago J. Macieira thiago at kemper.freedesktop.org
Sat Apr 29 05:44:33 PDT 2006


Update of /cvs/dbus/dbus/qt
In directory kemper:/tmp/cvs-serv11032/qt

Modified Files:
	qdbusabstractinterface.cpp qdbusabstractinterface.h qdbusbus.h 
	qdbusconnection.h qdbusconnection_p.h qdbusintegrator.cpp 
	qdbusinterface.cpp qdbusinterface.h qdbusinterface_p.h 
	qdbusinternalfilters.cpp 
Log Message:
        * qt/qdbusinterface.h: Rename QDBusRef to QDBusInterfacePtr
        and disable the copy operators. (r533772, r534746)

        * qt/qdbuserror.h: Remove the automatic cast to
          bool. (r533929)

        * qt/qdbusabstractinterface.cpp:
        * qt/qdbusabstractinterface.h: Change the default call mode to
        not use the event loop. Add convenience call() methods that
        take a CallMode parameter. (r534042)

        * qt/qdbusconnection.h: Change the default call mode to not
        use the event loop. (r534042)

        * qt/qdbusinterface.cpp:
        * qt/qdbusinterface.h: Add a method to tell us if the
        interface is valid (since we don't return a null pointer
        anymore) (r534099)

        * qt/qdbusinterface_p.h: Don't crash if metaObject is 0
        (r534101)

        * qt/qdbusinternalfilters.cpp: Decouple the introspection
        function in two so taht we get the chance to introspect
        without having a QDBusMessage (r534102)

        * qt/qdbusbus.h:
        * qt/qdbusconnection.cpp:
        * qt/qdbusconnection_p.h:
        * qt/qdbusintegrator.cpp: Keep a list of our own names to
        avoid a round-trip to the server when attempting to introspect
        one of our own objects. Also make sure the filter functions
        match the empty interface as well. (r534108)
        Don't keep the connection names. Instead, trust the unique
        connection name (r534111)
        Remove event loop usage (r534112)


Index: qdbusabstractinterface.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusabstractinterface.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- qdbusabstractinterface.cpp	23 Apr 2006 15:17:28 -0000	1.2
+++ qdbusabstractinterface.cpp	29 Apr 2006 12:44:31 -0000	1.3
@@ -148,7 +148,7 @@
 
     if (mode == AutoDetect) {
         // determine if this a sync or async call
-        mode = UseEventLoop;
+        mode = NoUseEventLoop;
         const QMetaObject *mo = metaObject();
         QByteArray match = method.toLatin1() + '(';
 

Index: qdbusabstractinterface.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusabstractinterface.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- qdbusabstractinterface.h	23 Apr 2006 15:17:28 -0000	1.2
+++ qdbusabstractinterface.h	29 Apr 2006 12:44:31 -0000	1.3
@@ -69,6 +69,11 @@
     {
         return callWithArgs(m);
     }
+
+    inline QDBusMessage call(CallMode mode, const QString &m)
+    {
+        return callWithArgs(m, QList<QVariant>(), mode);
+    }
     
 #ifndef Q_QDOC
 private:
@@ -152,6 +157,85 @@
              << qvfv(t7) << qvfv(t8);
         return callWithArgs(m, args);
     }
+
+    template<typename T1>
+    inline QDBusMessage call(CallMode mode, const QString &m, const T1 &t1)
+    {
+        QList<QVariant> args;
+        args << qvfv(t1);
+        return callWithArgs(m, args, mode);
+    }
+
+    template<typename T1, typename T2>
+    inline QDBusMessage call(CallMode mode, const QString &m, const T1 &t1, const T2 &t2)
+    {
+        QList<QVariant> args;
+        args << qvfv(t1) << qvfv(t2);
+        return callWithArgs(m, args, mode);
+    }
+
+    template<typename T1, typename T2, typename T3>
+    inline QDBusMessage call(CallMode mode, const QString &m, const T1 &t1, const T2 &t2,
+                             const T3 &t3)
+    {
+        QList<QVariant> args;
+        args << qvfv(t1) << qvfv(t2) << qvfv(t3);
+        return callWithArgs(m, args, mode);
+    }
+      
+    template<typename T1, typename T2, typename T3, typename T4>
+    inline QDBusMessage call(CallMode mode, const QString &m, const T1 &t1, const T2 &t2,
+                             const T3 &t3, const T4 &t4)
+    {
+        QList<QVariant> args;
+        args << qvfv(t1) << qvfv(t2) << qvfv(t3)
+             << qvfv(t4);
+        return callWithArgs(m, args, mode);
+    }
+
+    template<typename T1, typename T2, typename T3, typename T4, typename T5>
+    inline QDBusMessage call(CallMode mode, const QString &m, const T1 &t1, const T2 &t2,
+                             const T3 &t3, const T4 &t4, const T5 &t5)
+    {
+        QList<QVariant> args;
+        args << qvfv(t1) << qvfv(t2) << qvfv(t3)
+             << qvfv(t4) << qvfv(t5);
+        return callWithArgs(m, args, mode);
+    }
+  
+    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
+    inline QDBusMessage call(CallMode mode, const QString &m, const T1 &t1, const T2 &t2,
+                             const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6)
+    {
+        QList<QVariant> args;
+        args << qvfv(t1) << qvfv(t2) << qvfv(t3)
+             << qvfv(t4) << qvfv(t5) << qvfv(t6);
+        return callWithArgs(m, args, mode);
+    }
+
+    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
+    inline QDBusMessage call(CallMode mode, const QString &m, const T1 &t1, const T2 &t2,
+                             const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7)
+    {
+        QList<QVariant> args;
+        args << qvfv(t1) << qvfv(t2) << qvfv(t3)
+             << qvfv(t4) << qvfv(t5) << qvfv(t6)
+             << qvfv(t7);
+        return callWithArgs(m, args, mode);
+    }
+
+    template<typename T1, typename T2, typename T3, typename T4, typename T5,
+             typename T6, typename T7, typename T8>
+    inline QDBusMessage call(CallMode mode, const QString &m, const T1 &t1, const T2 &t2,
+                             const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7,
+                             const T8 &t8)
+    {
+        QList<QVariant> args;
+        args << qvfv(t1) << qvfv(t2) << qvfv(t3)
+             << qvfv(t4) << qvfv(t5) << qvfv(t6)
+             << qvfv(t7) << qvfv(t8);
+        return callWithArgs(m, args, mode);
+    }
 #endif
 
 protected:

Index: qdbusbus.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusbus.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- qdbusbus.h	28 Mar 2006 18:56:08 -0000	1.1
+++ qdbusbus.h	29 Apr 2006 12:44:31 -0000	1.2
@@ -150,7 +150,7 @@
 signals:
     void nameAcquired(const QString &service);
     void nameLost(const QString &service);
-    void nameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);    
+    void nameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
 };
 
 Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusBusService::RequestNameOptions);

Index: qdbusconnection.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusconnection.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- qdbusconnection.h	28 Mar 2006 18:56:08 -0000	1.6
+++ qdbusconnection.h	29 Apr 2006 12:44:31 -0000	1.7
@@ -74,7 +74,7 @@
     QDBusError lastError() const;
 
     bool send(const QDBusMessage &message) const;
-    QDBusMessage sendWithReply(const QDBusMessage &message, WaitMode mode = UseEventLoop) const;
+    QDBusMessage sendWithReply(const QDBusMessage &message, WaitMode mode = NoUseEventLoop) const;
     int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
                            const char *slot) const;
 

Index: qdbusconnection_p.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusconnection_p.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- qdbusconnection_p.h	23 Apr 2006 19:04:53 -0000	1.8
+++ qdbusconnection_p.h	29 Apr 2006 12:44:31 -0000	1.9
@@ -230,6 +230,7 @@
 extern bool qDBusCheckAsyncTag(const char *tag);
 
 // in qdbusinternalfilters.cpp
+extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode *node);
 extern void qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode *node,
                                   const QDBusMessage &msg);
 extern void qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode *node,

Index: qdbusintegrator.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusintegrator.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- qdbusintegrator.cpp	29 Apr 2006 10:07:42 -0000	1.9
+++ qdbusintegrator.cpp	29 Apr 2006 12:44:31 -0000	1.10
@@ -984,13 +984,14 @@
 {
     // object may be null
 
-    if (msg.interface() == QLatin1String(DBUS_INTERFACE_INTROSPECTABLE)) {
+    if (msg.interface().isEmpty() || msg.interface() == QLatin1String(DBUS_INTERFACE_INTROSPECTABLE)) {
         if (msg.method() == QLatin1String("Introspect") && msg.signature().isEmpty())
             qDBusIntrospectObject(node, msg);
         return true;
     }
 
-    if (node->obj && msg.interface() == QLatin1String(DBUS_INTERFACE_PROPERTIES)) {
+    if (node->obj && (msg.interface().isEmpty() ||
+                      msg.interface() == QLatin1String(DBUS_INTERFACE_PROPERTIES))) {
         if (msg.method() == QLatin1String("Get") && msg.signature() == QLatin1String("ss"))
             qDBusPropertyGet(node, msg);
         else if (msg.method() == QLatin1String("Set") && msg.signature() == QLatin1String("ssv"))
@@ -1053,25 +1054,26 @@
     return false;
 }
 
-bool QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
+template<typename Func>
+static bool applyForObject(QDBusConnectionPrivate::ObjectTreeNode *root, const QString &fullpath,
+                           Func& functor)
 {
-    QReadLocker locker(&lock);
-
     // walk the object tree
-    QStringList path = msg.path().split(QLatin1Char('/'));
+    QStringList path = fullpath.split(QLatin1Char('/'));
     if (path.last().isEmpty())
         path.removeLast();      // happens if path is "/"
     int i = 1;
-    ObjectTreeNode *node = &rootNode;
+    QDBusConnectionPrivate::ObjectTreeNode *node = root;
 
     // try our own tree first
     while (node && !(node->flags & QDBusConnection::ExportChildObjects) ) {
         if (i == path.count()) {
             // found our object
-            return activateObject(node, msg);
+            functor(node);
+            return true;
         }
 
-        QVector<ObjectTreeNode::Data>::ConstIterator it =
+        QVector<QDBusConnectionPrivate::ObjectTreeNode::Data>::ConstIterator it =
             qLowerBound(node->children.constBegin(), node->children.constEnd(), path.at(i));
         if (it != node->children.constEnd() && it->name == path.at(i))
             // match
@@ -1089,9 +1091,10 @@
         while (obj) {
             if (i == path.count()) {
                 // we're at the correct level
-                ObjectTreeNode fakenode(*node);
+                QDBusConnectionPrivate::ObjectTreeNode fakenode(*node);
                 fakenode.obj = obj;
-                return activateObject(&fakenode, msg);
+                functor(&fakenode);
+                return true;
             }
 
             const QObjectList &children = obj->children();
@@ -1112,6 +1115,31 @@
         }
     }
 
+    // object not found
+    return false;
+}
+
+struct qdbus_activateObject
+{
+    QDBusConnectionPrivate *self;
+    const QDBusMessage &msg;
+    bool returnVal;
+    inline qdbus_activateObject(QDBusConnectionPrivate *s, const QDBusMessage &m)
+        : self(s), msg(m)
+    { }
+
+    inline void operator()(QDBusConnectionPrivate::ObjectTreeNode *node)
+    { returnVal = self->activateObject(node, msg); }
+};
+
+bool QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
+{
+    QReadLocker locker(&lock);
+
+    qdbus_activateObject apply(this, msg);
+    if (applyForObject(&rootNode, msg.path(), apply))
+        return apply.returnVal;
+
     qDebug("Call failed: no object found at %s", qPrintable(msg.path()));
     return false;
 }
@@ -1479,6 +1507,7 @@
     QString owner = getNameOwner(service);
     if (connection && !owner.isEmpty() && QDBusUtil::isValidObjectPath(path) &&
         (interface.isEmpty() || QDBusUtil::isValidInterfaceName(interface)))
+        // always call here with the unique connection name
         mo = findMetaObject(owner, path, interface);
 
     QDBusInterfacePrivate *p = new QDBusInterfacePrivate(QDBusConnection(name), this, owner, path, interface, mo);
@@ -1509,24 +1538,52 @@
     return p;
 }
 
+struct qdbus_Introspect
+{
+    QString xml;
+    inline void operator()(QDBusConnectionPrivate::ObjectTreeNode *node)
+    { xml = qDBusIntrospectObject(node); }
+};
+
 QDBusMetaObject *
 QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &path,
                                        const QString &interface)
 {
+    // service must be a unique connection name
     if (!interface.isEmpty()) {
         QReadLocker locker(&lock);
         QDBusMetaObject *mo = cachedMetaObjects.value(interface, 0);
         if (mo)
             return mo;
     }
+    if (service == QString::fromUtf8(dbus_bus_get_unique_name(connection))) {
+        // it's one of our own
+        QWriteLocker locker(&lock);
+        QDBusMetaObject *mo = 0;
+        if (!interface.isEmpty())
+            mo = cachedMetaObjects.value(interface, 0);
+        if (mo)
+            // maybe it got created when we switched from read to write lock
+            return mo;
+
+        qdbus_Introspect apply;
+        if (!applyForObject(&rootNode, path, apply)) {
+            lastError = QDBusError(QDBusError::InvalidArgs,
+                                   QString(QLatin1String("No object at %1")).arg(path));
+            return 0;           // no object at path
+        }
+
+        // release the lock and return
+        return QDBusMetaObject::createMetaObject(interface, apply.xml, cachedMetaObjects, lastError);
+    }
 
-    // introspect the target object:
+    // not local: introspect the target object:
     QDBusMessage msg = QDBusMessage::methodCall(service, path,
                                                 QLatin1String(DBUS_INTERFACE_INTROSPECTABLE),
                                                 QLatin1String("Introspect"));
 
-    // we have to spin the event loop because the call could be targetting ourselves
-    QDBusMessage reply = sendWithReply(msg, QDBusConnection::UseEventLoop);
+
+    QDBusMessage reply = sendWithReply(msg, QDBusConnection::NoUseEventLoop);
 
     // it doesn't exist yet, we have to create it
     QWriteLocker locker(&lock);

Index: qdbusinterface.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusinterface.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- qdbusinterface.cpp	23 Apr 2006 19:04:53 -0000	1.5
+++ qdbusinterface.cpp	29 Apr 2006 12:44:31 -0000	1.6
@@ -58,6 +58,19 @@
 }
 
 /*!
+    Returns true if this is a valid reference to a remote object. It returns false if
+    there was an error during the creation of this interface (for instance, if the remote
+    application does not exist).
+
+    Note: when dealing with remote objects, it is not always possible to determine if it
+    exists when creating a QDBusInterface or QDBusInterfacePtr object.
+*/
+bool QDBusInterface::isValid() const
+{
+    return d_func()->isValid;
+}
+
+/*!
     \internal
     Overrides QObject::metaObject to return our own copy.
 */
@@ -238,13 +251,13 @@
     return id;
 }
 
-QDBusRef::QDBusRef(QDBusConnection &conn, const QString &service, const QString &path,
+QDBusInterfacePtr::QDBusInterfacePtr(QDBusConnection &conn, const QString &service, const QString &path,
                    const QString &interface)
     : d(conn.findInterface(service, path, interface))
 {
 }
 
-QDBusRef::QDBusRef(const QString &service, const QString &path, const QString &interface)
+QDBusInterfacePtr::QDBusInterfacePtr(const QString &service, const QString &path, const QString &interface)
     : d(QDBus::sessionBus().findInterface(service, path, interface))
 {
 }

Index: qdbusinterface.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusinterface.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- qdbusinterface.h	23 Apr 2006 19:04:53 -0000	1.4
+++ qdbusinterface.h	29 Apr 2006 12:44:31 -0000	1.5
@@ -35,6 +35,8 @@
     
 public:
     ~QDBusInterface();
+    bool isValid() const;
+    
     virtual const QMetaObject *metaObject() const;
     virtual void *qt_metacast(const char *);
     virtual int qt_metacall(QMetaObject::Call, int, void **);
@@ -43,16 +45,19 @@
     Q_DECLARE_PRIVATE(QDBusInterface);
 };
 
-struct QDBUS_EXPORT QDBusRef
+struct QDBUS_EXPORT QDBusInterfacePtr
 {
-    QDBusRef(QDBusConnection &conn, const QString &service, const QString &path,
+    QDBusInterfacePtr(QDBusInterface *iface) : d(iface) { }
+    QDBusInterfacePtr(QDBusConnection &conn, const QString &service, const QString &path,
              const QString &interface = QString());
-    QDBusRef(const QString &service, const QString &path, const QString &interface = QString());
-    ~QDBusRef() { delete d; }
+    QDBusInterfacePtr(const QString &service, const QString &path, const QString &interface = QString());
+    ~QDBusInterfacePtr() { delete d; }
 
-    QDBusInterface* operator->() const { return d; }
+    QDBusInterface *interface() { return d; }
+    QDBusInterface *operator->() { return d; }
 private:
     QDBusInterface *const d;
+    Q_DISABLE_COPY(QDBusInterfacePtr)
 };
 
 #endif

Index: qdbusinterface_p.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusinterface_p.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- qdbusinterface_p.h	28 Mar 2006 18:56:08 -0000	1.4
+++ qdbusinterface_p.h	29 Apr 2006 12:44:31 -0000	1.5
@@ -55,7 +55,7 @@
     }
     ~QDBusInterfacePrivate()
     {
-        if (!metaObject->cached)
+        if (metaObject && !metaObject->cached)
             delete metaObject;
     }
 

Index: qdbusinternalfilters.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusinternalfilters.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- qdbusinternalfilters.cpp	13 Apr 2006 17:34:18 -0000	1.4
+++ qdbusinternalfilters.cpp	29 Apr 2006 12:44:31 -0000	1.5
@@ -225,8 +225,7 @@
     return retval;
 }
 
-void qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode *node,
-                           const QDBusMessage &msg)
+QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode *node)
 {
     // object may be null
 
@@ -281,10 +280,15 @@
     }
 
     xml_data += QLatin1String("</node>\n");
+    return xml_data;
+}
 
+void qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode *node,
+                           const QDBusMessage &msg)
+{
     // now send it
     QDBusMessage reply = QDBusMessage::methodReply(msg);
-    reply << xml_data;
+    reply << qDBusIntrospectObject(node);
     msg.connection().send(reply);
 }
 



More information about the dbus-commit mailing list