diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2009-05-05 18:48:46 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2009-05-07 08:57:34 (GMT) |
commit | 83566cfac942c8ca7620cf95ae47655d6ff475c3 (patch) | |
tree | fed90947705d2c91bf9d21b799222e2ec76250e5 | |
parent | 0d8434ecfec5a088bc0c755964dae1dfcb35305e (diff) | |
download | Qt-83566cfac942c8ca7620cf95ae47655d6ff475c3.zip Qt-83566cfac942c8ca7620cf95ae47655d6ff475c3.tar.gz Qt-83566cfac942c8ca7620cf95ae47655d6ff475c3.tar.bz2 |
Make QDBusPendingCallWatcher emit a signal if it is created on an
already-finished call.
This fixes a bit of a "surprise" when calling a local method (which
returns and finishes immediately) or when by accident calling a
function that returns QDBusReply instead of QDBusPendingCall/Reply.
Reviewed-by: Trust Me
-rw-r--r-- | src/dbus/qdbuspendingcall.cpp | 10 | ||||
-rw-r--r-- | tests/auto/qdbuspendingcall/tst_qdbuspendingcall.cpp | 73 |
2 files changed, 81 insertions, 2 deletions
diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index 9753bbe..955f4a0 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -432,9 +432,14 @@ inline void QDBusPendingCallWatcherPrivate::_q_finished() QDBusPendingCallWatcher::QDBusPendingCallWatcher(const QDBusPendingCall &call, QObject *parent) : QObject(*new QDBusPendingCallWatcherPrivate, parent), QDBusPendingCall(call) { - if (d) { - if (!d->watcherHelper) + if (d) { // QDBusPendingCall::d + if (!d->watcherHelper) { d->watcherHelper = new QDBusPendingCallWatcherHelper; + if (isFinished()) { + // cause a signal emission anyways + QMetaObject::invokeMethod(d->watcherHelper, "finished", Qt::QueuedConnection); + } + } d->watcherHelper->add(this); } } @@ -464,6 +469,7 @@ void QDBusPendingCallWatcher::waitForFinished() d->waitForFinished(); // our signals were queued, so deliver them + QCoreApplication::sendPostedEvents(d->watcherHelper, QEvent::MetaCall); QCoreApplication::sendPostedEvents(this, QEvent::MetaCall); } } diff --git a/tests/auto/qdbuspendingcall/tst_qdbuspendingcall.cpp b/tests/auto/qdbuspendingcall/tst_qdbuspendingcall.cpp index 58707f1..947e8d6 100644 --- a/tests/auto/qdbuspendingcall/tst_qdbuspendingcall.cpp +++ b/tests/auto/qdbuspendingcall/tst_qdbuspendingcall.cpp @@ -90,6 +90,8 @@ private Q_SLOTS: void watcher(); void watcher_error(); void watcher_waitForFinished(); + void watcher_waitForFinished_alreadyFinished(); + void watcher_waitForFinished_alreadyFinished_eventLoop(); void watcher_waitForFinished_error(); void callInsideWaitForFinished(); @@ -375,6 +377,77 @@ void tst_QDBusPendingCall::watcher_waitForFinished() QVERIFY(args2.at(0).toStringList().contains(conn.baseService())); } +void tst_QDBusPendingCall::watcher_waitForFinished_alreadyFinished() +{ + QDBusPendingCall ac = sendMessage(); + QVERIFY(!ac.isFinished()); + QVERIFY(!ac.isError()); + QVERIFY(ac.reply().type() == QDBusMessage::InvalidMessage); + + ac.waitForFinished(); + QVERIFY(ac.isFinished()); + QVERIFY(!ac.isError()); + + callCount = 0; + watchArgument = 0; + + // create a watcher on an already-finished reply + QDBusPendingCallWatcher watch(ac); + connect(&watch, SIGNAL(finished(QDBusPendingCallWatcher*)), + SLOT(finished(QDBusPendingCallWatcher*))); + + watch.waitForFinished(); + + QVERIFY(ac.isFinished()); + QVERIFY(!ac.isError()); + + QCOMPARE(callCount, 1); + QCOMPARE(slotCalled, (int)FinishCalled); + QCOMPARE(watchArgument, &watch); + QVERIFY(!watch.isError()); + + const QVariantList args2 = ac.reply().arguments(); + QVERIFY(!args2.isEmpty()); + QVERIFY(args2.at(0).toStringList().contains(conn.baseService())); +} + +void tst_QDBusPendingCall::watcher_waitForFinished_alreadyFinished_eventLoop() +{ + QDBusPendingCall ac = sendMessage(); + QVERIFY(!ac.isFinished()); + QVERIFY(!ac.isError()); + QVERIFY(ac.reply().type() == QDBusMessage::InvalidMessage); + + ac.waitForFinished(); + QVERIFY(ac.isFinished()); + QVERIFY(!ac.isError()); + + callCount = 0; + watchArgument = 0; + + // create a watcher on an already-finished reply + QDBusPendingCallWatcher watch(ac); + connect(&watch, SIGNAL(finished(QDBusPendingCallWatcher*)), + SLOT(finished(QDBusPendingCallWatcher*))); + connect(&watch, SIGNAL(finished(QDBusPendingCallWatcher*)), + &QTestEventLoop::instance(), SLOT(exitLoop())); + + QTestEventLoop::instance().enterLoop(1); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QVERIFY(ac.isFinished()); + QVERIFY(!ac.isError()); + + QCOMPARE(callCount, 1); + QCOMPARE(slotCalled, (int)FinishCalled); + QCOMPARE(watchArgument, &watch); + QVERIFY(!watch.isError()); + + const QVariantList args2 = ac.reply().arguments(); + QVERIFY(!args2.isEmpty()); + QVERIFY(args2.at(0).toStringList().contains(conn.baseService())); +} + void tst_QDBusPendingCall::watcher_waitForFinished_error() { QDBusPendingCall ac = sendError(); |