+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
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);
};
int flags;
int slotIdx;
- bool generateReply : 1;
};
static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data)
}
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;
continue;
int returnType = returnTypeId(mm.typeName());
- isAsync = checkAsyncTag(mm.tag());
+ bool isAsync = checkAsyncTag(mm.tag());
// consistency check:
if (isAsync && returnType != QMetaType::Void)
data->message = msg;
data->metaTypes = metaTypes;
data->slotIdx = idx;
- data->generateReply = false;
QCoreApplication::postEvent( this, data );
// 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
QList<int> metaTypes;
int idx;
- bool isAsync;
int msgPos;
{
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;
// save our state:
call->metaTypes = metaTypes;
call->slotIdx = idx;
- call->generateReply = generateReply;
QCoreApplication::postEvent( this, call );
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;
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;
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);
#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
{
#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)
{
}
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;
}
message.d->name = name;
message.d->message = msg;
message.d->reply = dbus_message_ref(other.d->msg);
+ other.d->repliedTo = true;
return message;
}
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;
}
}
/*!
+ 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.
*/
}
/*!
+ 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.
*/
int timeout() const;
void setTimeout(int ms);
+ bool noReply() const;
+ void setNoReply(bool enable);
+
QString signature() const;
//protected:
static QDBusMessage fromError(const QDBusError& error);
int serialNumber() const;
int replySerialNumber() const;
+ bool wasRepliedTo() const;
private:
QDBusMessagePrivate *d;
int type;
int timeout;
QAtomic ref;
+
+ mutable bool repliedTo : 1;
};
#endif