summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/dbus/qdbusabstractinterface.cpp31
-rw-r--r--src/dbus/qdbusabstractinterface.h3
-rw-r--r--src/dbus/qdbusabstractinterface_p.h1
-rw-r--r--tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml4
-rw-r--r--tests/auto/qdbusabstractinterface/interface.cpp14
-rw-r--r--tests/auto/qdbusabstractinterface/interface.h1
-rw-r--r--tests/auto/qdbusabstractinterface/pinger.h7
-rw-r--r--tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp92
8 files changed, 149 insertions, 4 deletions
diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp
index 187ad67ddb..9f68313040 100644
--- a/src/dbus/qdbusabstractinterface.cpp
+++ b/src/dbus/qdbusabstractinterface.cpp
@@ -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;
@@ -384,6 +385,28 @@ QDBusError QDBusAbstractInterface::lastError() const
}
/*!
+ 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
QDBusMessage::ReplyMessage (indicating success) or QDBusMessage::ErrorMessage (if the call
@@ -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);
}
/*!
diff --git a/src/dbus/qdbusabstractinterface.h b/src/dbus/qdbusabstractinterface.h
index 72b922e499..34ff4107f9 100644
--- a/src/dbus/qdbusabstractinterface.h
+++ b/src/dbus/qdbusabstractinterface.h
@@ -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(),
diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h
index a000dafa8b..4f96165aa0 100644
--- a/src/dbus/qdbusabstractinterface_p.h
+++ b/src/dbus/qdbusabstractinterface_p.h
@@ -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
diff --git a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml
index 1667591708..d945ec9b43 100644
--- a/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml
+++ b/tests/auto/qdbusabstractinterface/com.trolltech.QtDBus.Pinger.xml
@@ -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>
diff --git a/tests/auto/qdbusabstractinterface/interface.cpp b/tests/auto/qdbusabstractinterface/interface.cpp
index 0326177fc0..849db93084 100644
--- a/tests/auto/qdbusabstractinterface/interface.cpp
+++ b/tests/auto/qdbusabstractinterface/interface.cpp
@@ -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"
diff --git a/tests/auto/qdbusabstractinterface/interface.h b/tests/auto/qdbusabstractinterface/interface.h
index b840a38e8e..0fb15fe6c5 100644
--- a/tests/auto/qdbusabstractinterface/interface.h
+++ b/tests/auto/qdbusabstractinterface/interface.h
@@ -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"; }
diff --git a/tests/auto/qdbusabstractinterface/pinger.h b/tests/auto/qdbusabstractinterface/pinger.h
index 6245a5a02f..739a14229f 100644
--- a/tests/auto/qdbusabstractinterface/pinger.h
+++ b/tests/auto/qdbusabstractinterface/pinger.h
@@ -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;
diff --git a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp
index 00e3a76d15..994df058fa 100644
--- a/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp
+++ b/tests/auto/qdbusabstractinterface/tst_qdbusabstractinterface.cpp
@@ -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();