From 602809693a5b9a20c83a5726cee0a6426bc2a6f3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 20 Feb 2006 13:23:11 +0000 Subject: 2006-02-20 Thiago Macieira * qt/qdbusinterface_p.h: * qt/qdbusinterface.cpp: Use the standard org.freedesktop.DBus.Method.NoReply annotation for the "async" calls instead of creating one for us. * qt/qdbusconnection_p.h: * qt/qdbusintegrator.cpp: Remove debugging code. * qt/qdbusintegrator.cpp: * qt/qdbusmessage.cpp: * qt/qdbusmessage_p.h: * qt/qdbusmessage.h: Change the behaviour of automatic reply-sending: now a reply is always sent, unless the caller didn't request one or if the user slot has already sent one. --- qt/qdbusconnection_p.h | 6 ----- qt/qdbusintegrator.cpp | 63 +++++++++----------------------------------------- qt/qdbusinterface.cpp | 2 +- qt/qdbusinterface_p.h | 2 +- qt/qdbusmessage.cpp | 39 ++++++++++++++++++++++++++++++- qt/qdbusmessage.h | 4 ++++ qt/qdbusmessage_p.h | 2 ++ 7 files changed, 57 insertions(+), 61 deletions(-) (limited to 'qt') diff --git a/qt/qdbusconnection_p.h b/qt/qdbusconnection_p.h index fa0fdd82..cd2e48e2 100644 --- a/qt/qdbusconnection_p.h +++ b/qt/qdbusconnection_p.h @@ -180,12 +180,6 @@ class QDBusReplyWaiter: public QEventLoop public: QDBusMessage replyMsg; -#ifndef QT_NO_DEBUG - int level; - int exec(ProcessEventsFlags flags); - void exit(int = 0); -#endif - public slots: void reply(const QDBusMessage &msg); }; diff --git a/qt/qdbusintegrator.cpp b/qt/qdbusintegrator.cpp index 79baa101..4c123d1d 100644 --- a/qt/qdbusintegrator.cpp +++ b/qt/qdbusintegrator.cpp @@ -62,7 +62,6 @@ public: int flags; int slotIdx; - bool generateReply : 1; }; static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data) @@ -418,7 +417,7 @@ static int parametersForMethod(const QByteArray &sig, QList& metaTypes) } static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags, - const QDBusTypeList &types, QList& metaTypes, bool &isAsync, int &msgPos) + const QDBusTypeList &types, QList& metaTypes, int &msgPos) { // find the first slot const QMetaObject *super = mo; @@ -448,7 +447,7 @@ static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags, continue; int returnType = returnTypeId(mm.typeName()); - isAsync = checkAsyncTag(mm.tag()); + bool isAsync = checkAsyncTag(mm.tag()); // consistency check: if (isAsync && returnType != QMetaType::Void) @@ -543,7 +542,6 @@ bool QDBusConnectionPrivate::activateReply(QObject *object, int idx, const QList data->message = msg; data->metaTypes = metaTypes; data->slotIdx = idx; - data->generateReply = false; QCoreApplication::postEvent( this, data ); @@ -567,15 +565,10 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, // the original types, the message signature is used to determine the original type. // Aside from that, the "int" and "unsigned" types will be tried as well. // - // Return message handling depends on whether the asynchronous tag ("async" or "Q_ASYNC") - // tag is found, whether the slot takes a QDBusMessage parameter and whether there are - // return values (non-const reference parameters or a return type). - // The table indicates the possibilities: - // async QDBusMessage parameter return values return message generated - // yes irrelevant irrelevant no - // no irrelevant yes yes - // no yes no no - // no no no yes + // The D-Bus specification requires that all MethodCall messages be replied to, unless the + // caller specifically waived this requirement. This means that we inspect if the user slot + // generated a reply and, if it didn't, we will. Obviously, if the user slot doesn't take a + // QDBusMessage parameter, it cannot generate a reply. // // When a return message is generated, the slot's return type, if any, will be placed // in the message's first position. If there are non-const reference parameters to the @@ -586,7 +579,6 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, QList metaTypes; int idx; - bool isAsync; int msgPos; { @@ -594,26 +586,12 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, QDBusTypeList typeList(msg.signature().toUtf8()); // find a slot that matches according to the rules above - idx = ::findSlot(mo, msg.name().toUtf8(), flags, typeList, metaTypes, isAsync, msgPos); + idx = ::findSlot(mo, msg.name().toUtf8(), flags, typeList, metaTypes, msgPos); if (idx == -1) // no match return false; } - bool generateReply; - if (isAsync) - generateReply = false; - else if (metaTypes[0] != QMetaType::Void) - generateReply = true; - else { - if (msgPos != 0) - // generate a reply if there are more parameters past QDBusMessage - generateReply = metaTypes.count() > msgPos + 1; - else - // generate a reply if there are more parameters than input parameters - generateReply = metaTypes.count() > msg.count() + 1; - } - // found the slot to be called // prepare for the call: CallDeliveryEvent *call = new CallDeliveryEvent; @@ -627,7 +605,6 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, // save our state: call->metaTypes = metaTypes; call->slotIdx = idx; - call->generateReply = generateReply; QCoreApplication::postEvent( this, call ); @@ -715,10 +692,11 @@ void QDBusConnectionPrivate::deliverCall(const CallDeliveryEvent& data) const fail = data.object->qt_metacall(QMetaObject::InvokeMetaMethod, data.slotIdx, params.data()) >= 0; - // do we create a reply? - if (data.generateReply) { + // do we create a reply? Only if the caller is waiting for a reply and one hasn't been sent + // yet. + if (!msg.noReply() && !msg.wasRepliedTo()) { if (!fail) { - // yes + // normal reply QDBusMessage reply = QDBusMessage::methodReply(msg); reply += outputArgs; @@ -1209,25 +1187,6 @@ void QDBusConnectionPrivate::disposeOf(QDBusObjectPrivate* p) disposeOfLocked( const_cast(p->data) ); } -#ifndef QT_NO_DEBUG -int QDBusReplyWaiter::exec(QEventLoop::ProcessEventsFlags flags) -{ - static int eventlevel; - level = ++eventlevel; - qDebug("QDBusReplyWaiter::exec %p level %d starting", this, level); - int retcode = QEventLoop::exec(flags); - qDebug("QDBusReplyWaiter::exec %p level %d exiting", this, level); - --eventlevel; - return retcode; -} - -void QDBusReplyWaiter::exit(int retcode) -{ - qDebug("QDBusReplyWaiter::exit %p level %d called", this, level); - QEventLoop::exit(retcode); -} -#endif - void QDBusReplyWaiter::reply(const QDBusMessage &msg) { replyMsg = msg; diff --git a/qt/qdbusinterface.cpp b/qt/qdbusinterface.cpp index 36354fc1..d1b73d58 100644 --- a/qt/qdbusinterface.cpp +++ b/qt/qdbusinterface.cpp @@ -142,7 +142,7 @@ QDBusMessage QDBusInterface::callWithArgs(const QDBusIntrospection::Method& meth else args.clear(); - if (method.annotations.contains(ANNOTATION_NO_WAIT)) + if (method.annotations.value(ANNOTATION_NO_WAIT, "false") == "true") mode = NoWaitForReply; return callWithArgs(method.name, signature, args, mode); diff --git a/qt/qdbusinterface_p.h b/qt/qdbusinterface_p.h index 52fa8008..3e0bd010 100644 --- a/qt/qdbusinterface_p.h +++ b/qt/qdbusinterface_p.h @@ -42,7 +42,7 @@ #include "qdbusconnection.h" #include "qdbuserror.h" -#define ANNOTATION_NO_WAIT "com.trolltech.DBus.NoWaitForReply" +#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply" class QDBusInterfacePrivate { diff --git a/qt/qdbusmessage.cpp b/qt/qdbusmessage.cpp index 5c604c13..b88d7e39 100644 --- a/qt/qdbusmessage.cpp +++ b/qt/qdbusmessage.cpp @@ -34,7 +34,8 @@ #include "qdbusmessage_p.h" QDBusMessagePrivate::QDBusMessagePrivate(QDBusMessage *qq) - : msg(0), reply(0), q(qq), type(DBUS_MESSAGE_TYPE_INVALID), timeout(-1), ref(1) + : msg(0), reply(0), q(qq), type(DBUS_MESSAGE_TYPE_INVALID), timeout(-1), ref(1), + repliedTo(false) { } @@ -143,6 +144,7 @@ QDBusMessage QDBusMessage::methodReply(const QDBusMessage &other) QDBusMessage message; message.d->type = DBUS_MESSAGE_TYPE_METHOD_RETURN; message.d->reply = dbus_message_ref(other.d->msg); + other.d->repliedTo = true; return message; } @@ -166,6 +168,7 @@ QDBusMessage QDBusMessage::error(const QDBusMessage &other, const QString &name, message.d->name = name; message.d->message = msg; message.d->reply = dbus_message_ref(other.d->msg); + other.d->repliedTo = true; return message; } @@ -187,6 +190,7 @@ QDBusMessage QDBusMessage::error(const QDBusMessage &other, const QDBusError &er message.d->name = error.name(); message.d->message = error.message(); message.d->reply = dbus_message_ref(other.d->msg); + other.d->repliedTo = true; return message; } @@ -370,6 +374,30 @@ void QDBusMessage::setTimeout(int ms) d->timeout = ms; } +/*! + Returns the flag that indicates if this message should see a reply or not. This is only + meaningful for MethodCall messages: any other kind of message cannot have replies and this + function will always return false for them. +*/ +bool QDBusMessage::noReply() const +{ + if (!d->msg) + return false; + return dbus_message_get_no_reply(d->msg); +} + +/*! + Sets the flag that indicates whether we're expecting a reply from the callee. This flag only + makes sense for MethodCall messages. + + \param enable whether to enable the flag (i.e., we are not expecting a reply) +*/ +void QDBusMessage::setNoReply(bool enable) +{ + if (d->msg) + dbus_message_set_no_reply(d->msg, enable); +} + /*! Returns the unique serial number assigned to this message or 0 if the message was not sent yet. @@ -396,6 +424,15 @@ int QDBusMessage::replySerialNumber() const return dbus_message_get_reply_serial(d->msg); } +/*! + Returns true if this is a MethodCall message and a reply for it has been generated using + QDBusMessage::methodReply or QDBusMessage::error. +*/ +bool QDBusMessage::wasRepliedTo() const +{ + return d->repliedTo; +} + /*! Returns the signature of the signal that was received or for the output arguments of a method call. diff --git a/qt/qdbusmessage.h b/qt/qdbusmessage.h index 6c480444..7c190c62 100644 --- a/qt/qdbusmessage.h +++ b/qt/qdbusmessage.h @@ -71,6 +71,9 @@ public: int timeout() const; void setTimeout(int ms); + bool noReply() const; + void setNoReply(bool enable); + QString signature() const; //protected: @@ -79,6 +82,7 @@ public: static QDBusMessage fromError(const QDBusError& error); int serialNumber() const; int replySerialNumber() const; + bool wasRepliedTo() const; private: QDBusMessagePrivate *d; diff --git a/qt/qdbusmessage_p.h b/qt/qdbusmessage_p.h index 9c48b084..ef633242 100644 --- a/qt/qdbusmessage_p.h +++ b/qt/qdbusmessage_p.h @@ -42,6 +42,8 @@ public: int type; int timeout; QAtomic ref; + + mutable bool repliedTo : 1; }; #endif -- cgit