summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog38
-rw-r--r--qt/qdbusabstractinterface.cpp2
-rw-r--r--qt/qdbusabstractinterface.h84
-rw-r--r--qt/qdbusbus.h2
-rw-r--r--qt/qdbusconnection.h2
-rw-r--r--qt/qdbusconnection_p.h1
-rw-r--r--qt/qdbusintegrator.cpp85
-rw-r--r--qt/qdbusinterface.cpp17
-rw-r--r--qt/qdbusinterface.h15
-rw-r--r--qt/qdbusinterface_p.h2
-rw-r--r--qt/qdbusinternalfilters.cpp10
11 files changed, 230 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index 7a07e132..c29fb746 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,43 @@
2006-04-29 Thiago Macieira <thiago.macieira@trolltech.com>
+ * 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)
+
+2006-04-29 Thiago Macieira <thiago.macieira@trolltech.com>
+
* qt/qdbusintegrator.cpp: Fix assertion failure spotted by
Brad Hards.
diff --git a/qt/qdbusabstractinterface.cpp b/qt/qdbusabstractinterface.cpp
index 291888fe..eec373a3 100644
--- a/qt/qdbusabstractinterface.cpp
+++ b/qt/qdbusabstractinterface.cpp
@@ -148,7 +148,7 @@ QDBusMessage QDBusAbstractInterface::callWithArgs(const QString& method, const Q
if (mode == AutoDetect) {
// determine if this a sync or async call
- mode = UseEventLoop;
+ mode = NoUseEventLoop;
const QMetaObject *mo = metaObject();
QByteArray match = method.toLatin1() + '(';
diff --git a/qt/qdbusabstractinterface.h b/qt/qdbusabstractinterface.h
index ae80b0a3..23f928a2 100644
--- a/qt/qdbusabstractinterface.h
+++ b/qt/qdbusabstractinterface.h
@@ -69,6 +69,11 @@ public:
{
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 @@ public:
<< 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:
diff --git a/qt/qdbusbus.h b/qt/qdbusbus.h
index ae2720e2..6f0bbb1c 100644
--- a/qt/qdbusbus.h
+++ b/qt/qdbusbus.h
@@ -150,7 +150,7 @@ public slots:
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);
diff --git a/qt/qdbusconnection.h b/qt/qdbusconnection.h
index 60116e10..e107242b 100644
--- a/qt/qdbusconnection.h
+++ b/qt/qdbusconnection.h
@@ -74,7 +74,7 @@ public:
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;
diff --git a/qt/qdbusconnection_p.h b/qt/qdbusconnection_p.h
index 36f21db7..af572084 100644
--- a/qt/qdbusconnection_p.h
+++ b/qt/qdbusconnection_p.h
@@ -230,6 +230,7 @@ extern int qDBusNameToTypeId(const char *name);
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,
diff --git a/qt/qdbusintegrator.cpp b/qt/qdbusintegrator.cpp
index bef8268d..3f907256 100644
--- a/qt/qdbusintegrator.cpp
+++ b/qt/qdbusintegrator.cpp
@@ -984,13 +984,14 @@ bool QDBusConnectionPrivate::activateInternalFilters(const ObjectTreeNode *node,
{
// 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 @@ bool QDBusConnectionPrivate::activateObject(const ObjectTreeNode *node, const QD
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 @@ bool QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
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 @@ bool QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
}
}
+ // 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 @@ QDBusConnectionPrivate::findInterface(const QString &service,
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 @@ QDBusConnectionPrivate::findInterface(const QString &service,
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);
diff --git a/qt/qdbusinterface.cpp b/qt/qdbusinterface.cpp
index ff8fdc95..48b1011c 100644
--- a/qt/qdbusinterface.cpp
+++ b/qt/qdbusinterface.cpp
@@ -58,6 +58,19 @@ QDBusInterface::~QDBusInterface()
}
/*!
+ 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 @@ int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv)
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))
{
}
diff --git a/qt/qdbusinterface.h b/qt/qdbusinterface.h
index f667698b..2e16e5ce 100644
--- a/qt/qdbusinterface.h
+++ b/qt/qdbusinterface.h
@@ -35,6 +35,8 @@ private:
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 @@ private:
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
diff --git a/qt/qdbusinterface_p.h b/qt/qdbusinterface_p.h
index 70b732c2..25cb9ffa 100644
--- a/qt/qdbusinterface_p.h
+++ b/qt/qdbusinterface_p.h
@@ -55,7 +55,7 @@ public:
}
~QDBusInterfacePrivate()
{
- if (!metaObject->cached)
+ if (metaObject && !metaObject->cached)
delete metaObject;
}
diff --git a/qt/qdbusinternalfilters.cpp b/qt/qdbusinternalfilters.cpp
index fe57a875..3d454277 100644
--- a/qt/qdbusinternalfilters.cpp
+++ b/qt/qdbusinternalfilters.cpp
@@ -225,8 +225,7 @@ static QString generateSubObjectXml(QObject *object)
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 @@ void qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode *node,
}
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);
}