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.
This commit is contained in:
Thiago Macieira 2006-02-20 13:23:11 +00:00
parent 4dedbb4984
commit 602809693a
8 changed files with 79 additions and 66 deletions

View file

@ -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
@ -162,17 +179,17 @@
<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/}@/@})
@ -11152,7 +11169,7 @@
* 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
@ -12990,7 +13007,7 @@
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

View 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);
};

View 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;

View 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);

View 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
{

View 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;
}
@ -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.

View 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;

View file

@ -42,6 +42,8 @@ public:
int type;
int timeout;
QAtomic ref;
mutable bool repliedTo : 1;
};
#endif