2006-02-20 Thiago Macieira <thiago.macieira@trolltech.com>
authorThiago Macieira <thiago@kde.org>
Mon, 20 Feb 2006 13:23:11 +0000 (13:23 +0000)
committerThiago Macieira <thiago@kde.org>
Mon, 20 Feb 2006 13:23:11 +0000 (13:23 +0000)
* 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.

ChangeLog
qt/qdbusconnection_p.h
qt/qdbusintegrator.cpp
qt/qdbusinterface.cpp
qt/qdbusinterface_p.h
qt/qdbusmessage.cpp
qt/qdbusmessage.h
qt/qdbusmessage_p.h

index d9ab170..dfbb100 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2006-02-20  Thiago Macieira <thiago.macieira@trolltech.com>
+
+       * 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.
+
 2006-02-16  Robert McQueen  <robot101@debian.org>
 
        * configure.in: Patch from Debian packages by Sjoerd Simons
        <ricardo.kekki@movial.fi> to make dbus-binding-tool heed C symbol name
        annotations when generating glib client bindings.
 
-2005-12-19 John (J5) Palmieri  <johnp@redhat.com>
+1999-11-30  John (J5) Palmieri  <johnp@redhat.com>
 
        * dbus/dbus-shared.h: Call it shared constants instead of shared macros
 
        * dbus/dbus-protocol.h: add DOxygen markup to quiet warnings
 
-2005-12-19 John (J5) Palmieri  <johnp@redhat.com>
+1999-11-30  John (J5) Palmieri  <johnp@redhat.com>
 
        * dbus/dbus-shared.h: add DOxygen markup to quiet warnings
 
-2005-12-19 John (J5) Palmieri  <johnp@redhat.com> 
+1999-11-30  John (J5) Palmieri  <johnp@redhat.com> 
 
        * dbus/dbus-macros.h: correct DOxygen end of section (s/}@/@})
 
        * bus/main.c: (main):
        Add simple activation support, doesn't work yet though.
 
-2003-02-15   Zack Rusin  <zack@kde.org>
+1999-11-30  Zack Rusin  <zack@kde.org>
 
        * qt/dbus-qthread.cpp:  small casting fix
 
        because any app can be a server, and any app can be a client,
        the bus is a special kind of server.
 
-Thu Nov 21 23:35:31 2002  Zack Rusin  <zack@kde.org>
+2002-11-22  Zack Rusin  <zack@kde.org>
 
        * Doxyfile : adding. Still needs Makefile rules to be generated
        automatically (just run "doxygen" in the toplevel dir for now to
index fa0fdd8..cd2e48e 100644 (file)
@@ -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);
 };    
index 79baa10..4c123d1 100644 (file)
@@ -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<int>& metaTypes)
 }
 
 static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags,
-                    const QDBusTypeList &types, QList<int>& metaTypes, bool &isAsync, int &msgPos)
+                    const QDBusTypeList &types, QList<int>& 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<int> 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<QDBusIntrospection::Object*>(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;
index 36354fc..d1b73d5 100644 (file)
@@ -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);
index 52fa800..3e0bd01 100644 (file)
@@ -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
 {
index 5c604c1..b88d7e3 100644 (file)
@@ -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;
 }
@@ -371,6 +375,30 @@ void QDBusMessage::setTimeout(int 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.
  */
@@ -397,6 +425,15 @@ int QDBusMessage::replySerialNumber() const
 }
 
 /*!
+    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.
 */
index 6c48044..7c190c6 100644 (file)
@@ -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;
index 9c48b08..ef63324 100644 (file)
@@ -42,6 +42,8 @@ public:
     int type;
     int timeout;
     QAtomic ref;
+
+    mutable bool repliedTo : 1;
 };
 
 #endif