Make the DBus timeout configurable in QDBusAbstractInterface.
Merge-request: 1253 Reviewed-by: Thiago Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com> (cherry picked from commit e58a402fbee2fc8af8cd651acafdc28525ed1314) Change-Id: I4246047b149193e510f2984a0b1a1fae655b9a51 Reviewed-on: http://codereview.qt.nokia.com/3580 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com>bb10
parent
bdc417b382
commit
7347a5f99d
|
|
@ -88,6 +88,7 @@ QDBusAbstractInterfacePrivate::QDBusAbstractInterfacePrivate(const QString &serv
|
|||
: connection(con), service(serv), path(p), interface(iface),
|
||||
lastError(checkIfValid(serv, p, iface, isDynamic, (connectionPrivate() &&
|
||||
connectionPrivate()->mode == QDBusConnectionPrivate::PeerMode))),
|
||||
timeout(-1),
|
||||
isValid(!lastError.isValid())
|
||||
{
|
||||
if (!isValid)
|
||||
|
|
@ -144,7 +145,7 @@ void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &
|
|||
QLatin1String("Get"));
|
||||
QDBusMessagePrivate::setParametersValidated(msg, true);
|
||||
msg << interface << QString::fromUtf8(mp.name());
|
||||
QDBusMessage reply = connection.call(msg, QDBus::Block);
|
||||
QDBusMessage reply = connection.call(msg, QDBus::Block, timeout);
|
||||
|
||||
if (reply.type() != QDBusMessage::ReplyMessage) {
|
||||
lastError = reply;
|
||||
|
|
@ -210,7 +211,7 @@ bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const Q
|
|||
QLatin1String("Set"));
|
||||
QDBusMessagePrivate::setParametersValidated(msg, true);
|
||||
msg << interface << QString::fromUtf8(mp.name()) << QVariant::fromValue(QDBusVariant(value));
|
||||
QDBusMessage reply = connection.call(msg, QDBus::Block);
|
||||
QDBusMessage reply = connection.call(msg, QDBus::Block, timeout);
|
||||
|
||||
if (reply.type() != QDBusMessage::ReplyMessage) {
|
||||
lastError = reply;
|
||||
|
|
@ -383,6 +384,28 @@ QDBusError QDBusAbstractInterface::lastError() const
|
|||
return d_func()->lastError;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the timeout in seconds for all future DBus calls to \a timeout.
|
||||
-1 means the default DBus timeout (usually 25 seconds).
|
||||
|
||||
\since 4.8
|
||||
*/
|
||||
void QDBusAbstractInterface::setTimeout(int timeout)
|
||||
{
|
||||
d_func()->timeout = timeout;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the current value of the timeout in seconds.
|
||||
-1 means the default DBus timeout (usually 25 seconds).
|
||||
|
||||
\since 4.8
|
||||
*/
|
||||
int QDBusAbstractInterface::timeout() const
|
||||
{
|
||||
return d_func()->timeout;
|
||||
}
|
||||
|
||||
/*!
|
||||
Places a call to the remote method specified by \a method on this interface, using \a args as
|
||||
arguments. This function returns the message that was received as a reply, which can be a normal
|
||||
|
|
@ -442,7 +465,7 @@ QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode,
|
|||
QDBusMessagePrivate::setParametersValidated(msg, true);
|
||||
msg.setArguments(args);
|
||||
|
||||
QDBusMessage reply = d->connection.call(msg, mode);
|
||||
QDBusMessage reply = d->connection.call(msg, mode, d->timeout);
|
||||
if (thread() == QThread::currentThread())
|
||||
d->lastError = reply; // will clear if reply isn't an error
|
||||
|
||||
|
|
@ -475,7 +498,7 @@ QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString
|
|||
QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method);
|
||||
QDBusMessagePrivate::setParametersValidated(msg, true);
|
||||
msg.setArguments(args);
|
||||
return d->connection.asyncCall(msg);
|
||||
return d->connection.asyncCall(msg, d->timeout);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -95,6 +95,9 @@ public:
|
|||
|
||||
QDBusError lastError() const;
|
||||
|
||||
void setTimeout(int timeout);
|
||||
int timeout() const;
|
||||
|
||||
QDBusMessage call(const QString &method,
|
||||
const QVariant &arg1 = QVariant(),
|
||||
const QVariant &arg2 = QVariant(),
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ public:
|
|||
QString path;
|
||||
QString interface;
|
||||
mutable QDBusError lastError;
|
||||
int timeout;
|
||||
|
||||
// this is set during creation and never changed
|
||||
// it can't be const because QDBusInterfacePrivate has one more check
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@
|
|||
<annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="RegisteredType"/>
|
||||
</signal>
|
||||
<method name="voidMethod" />
|
||||
<method name="sleepMethod">
|
||||
<arg type="i" />
|
||||
<arg type="i" direction="out"/>
|
||||
</method>
|
||||
<method name="stringMethod">
|
||||
<arg type="s" direction="out"/>
|
||||
</method>
|
||||
|
|
|
|||
|
|
@ -40,9 +40,23 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "interface.h"
|
||||
#include <QThread>
|
||||
|
||||
Interface::Interface()
|
||||
{
|
||||
}
|
||||
|
||||
// Export the sleep function
|
||||
// TODO QT5: remove this class, QThread::msleep is now public
|
||||
class FriendlySleepyThread : public QThread {
|
||||
public:
|
||||
using QThread::msleep;
|
||||
};
|
||||
|
||||
int Interface::sleepMethod(int msec)
|
||||
{
|
||||
FriendlySleepyThread::msleep(msec);
|
||||
return 42;
|
||||
}
|
||||
|
||||
#include "moc_interface.cpp"
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public:
|
|||
|
||||
public slots:
|
||||
Q_SCRIPTABLE void voidMethod() {}
|
||||
Q_SCRIPTABLE int sleepMethod(int);
|
||||
Q_SCRIPTABLE QString stringMethod() { return "Hello, world"; }
|
||||
Q_SCRIPTABLE RegisteredType complexMethod() { return RegisteredType("Hello, world"); }
|
||||
Q_SCRIPTABLE QString multiOutMethod(int &value) { value = 42; return "Hello, world"; }
|
||||
|
|
|
|||
|
|
@ -117,6 +117,13 @@ public Q_SLOTS: // METHODS
|
|||
return reply;
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<int> sleepMethod(int in0)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << qVariantFromValue(in0);
|
||||
return asyncCallWithArgumentList(QLatin1String("sleepMethod"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<QString> stringMethod()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ private slots:
|
|||
void makeAsyncComplexCallPeer();
|
||||
void makeAsyncMultiOutCallPeer();
|
||||
|
||||
void callWithTimeout();
|
||||
|
||||
void stringPropRead();
|
||||
void stringPropWrite();
|
||||
void variantPropRead();
|
||||
|
|
@ -458,6 +460,96 @@ void tst_QDBusAbstractInterface::makeAsyncMultiOutCallPeer()
|
|||
QCoreApplication::instance()->processEvents();
|
||||
}
|
||||
|
||||
static const char server_serviceName[] = "com.trolltech.autotests.dbusserver";
|
||||
static const char server_objectPath[] = "/com/trolltech/server";
|
||||
static const char server_interfaceName[] = "com.trolltech.QtDBus.Pinger";
|
||||
|
||||
class DBusServerThread : public QThread
|
||||
{
|
||||
public:
|
||||
DBusServerThread() {
|
||||
start();
|
||||
m_ready.acquire();
|
||||
}
|
||||
~DBusServerThread() {
|
||||
quit();
|
||||
wait();
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::connectToBus(QDBusConnection::SessionBus, "ThreadConnection");
|
||||
if (!con.isConnected())
|
||||
qWarning("Error registering to DBus");
|
||||
if (!con.registerService(server_serviceName))
|
||||
qWarning("Error registering service name");
|
||||
Interface targetObj;
|
||||
con.registerObject(server_objectPath, &targetObj, QDBusConnection::ExportScriptableContents);
|
||||
m_ready.release();
|
||||
exec();
|
||||
|
||||
QDBusConnection::disconnectFromBus( con.name() );
|
||||
}
|
||||
private:
|
||||
QSemaphore m_ready;
|
||||
};
|
||||
|
||||
void tst_QDBusAbstractInterface::callWithTimeout()
|
||||
{
|
||||
QDBusConnection con = QDBusConnection::sessionBus();
|
||||
QVERIFY2(con.isConnected(), "Not connected to D-Bus");
|
||||
|
||||
DBusServerThread serverThread;
|
||||
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(server_serviceName,
|
||||
server_objectPath, server_interfaceName, "sleepMethod");
|
||||
msg << 100;
|
||||
|
||||
{
|
||||
// Call with no timeout -> works
|
||||
QDBusMessage reply = con.call(msg);
|
||||
QCOMPARE((int)reply.type(), (int)QDBusMessage::ReplyMessage);
|
||||
QCOMPARE(reply.arguments().at(0).toInt(), 42);
|
||||
}
|
||||
|
||||
{
|
||||
// Call with 1 sec timeout -> fails
|
||||
QDBusMessage reply = con.call(msg, QDBus::Block, 1);
|
||||
QCOMPARE(reply.type(), QDBusMessage::ErrorMessage);
|
||||
}
|
||||
|
||||
// Now using QDBusInterface
|
||||
|
||||
QDBusInterface iface(server_serviceName, server_objectPath, server_interfaceName, con);
|
||||
{
|
||||
// Call with no timeout
|
||||
QDBusMessage reply = iface.call("sleepMethod", 100);
|
||||
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
|
||||
QCOMPARE(reply.arguments().at(0).toInt(), 42);
|
||||
}
|
||||
{
|
||||
// Call with 1 sec timeout -> fails
|
||||
iface.setTimeout(1);
|
||||
QDBusMessage reply = iface.call("sleepMethod", 100);
|
||||
QCOMPARE(reply.type(), QDBusMessage::ErrorMessage);
|
||||
}
|
||||
|
||||
// Now using generated code
|
||||
com::trolltech::QtDBus::Pinger p(server_serviceName, server_objectPath, QDBusConnection::sessionBus());
|
||||
{
|
||||
// Call with no timeout
|
||||
QDBusReply<int> reply = p.sleepMethod(100);
|
||||
QVERIFY(reply.isValid());
|
||||
QCOMPARE(int(reply), 42);
|
||||
}
|
||||
{
|
||||
// Call with 1 sec timeout -> fails
|
||||
p.setTimeout(1);
|
||||
QDBusReply<int> reply = p.sleepMethod(100);
|
||||
QVERIFY(!reply.isValid());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDBusAbstractInterface::stringPropRead()
|
||||
{
|
||||
Pinger p = getPinger();
|
||||
|
|
|
|||
Loading…
Reference in New Issue