[Telepathy-commits] [telepathy-qt4/master] PendingHandles: Do not fail if one of the requested identifiers is valid.
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Tue Mar 24 09:36:28 PDT 2009
Added validIds, invalidIds methods.
---
TelepathyQt4/Client/connection.cpp | 29 +------
TelepathyQt4/Client/pending-handles.cpp | 155 +++++++++++++++++++++++++++++--
TelepathyQt4/Client/pending-handles.h | 8 ++-
tests/dbus/contacts.cpp | 4 +-
4 files changed, 156 insertions(+), 40 deletions(-)
diff --git a/TelepathyQt4/Client/connection.cpp b/TelepathyQt4/Client/connection.cpp
index b25d89f..93ce159 100644
--- a/TelepathyQt4/Client/connection.cpp
+++ b/TelepathyQt4/Client/connection.cpp
@@ -1161,15 +1161,6 @@ PendingHandles *Connection::requestHandles(uint handleType, const QStringList &n
PendingHandles *pending =
new PendingHandles(this, handleType, names);
- QDBusPendingCallWatcher *watcher =
- new QDBusPendingCallWatcher(
- mPriv->baseInterface->RequestHandles(handleType, names),
- pending);
-
- pending->connect(watcher,
- SIGNAL(finished(QDBusPendingCallWatcher *)),
- SLOT(onCallFinished(QDBusPendingCallWatcher *)));
-
return pending;
}
@@ -1223,24 +1214,8 @@ PendingHandles *Connection::referenceHandles(uint handleType, const UIntList &ha
"of the handles -" << notYetHeld.size() << "to go";
PendingHandles *pending =
- new PendingHandles(this, handleType, handles, alreadyHeld);
-
- if (!notYetHeld.isEmpty()) {
- debug() << " Calling HoldHandles";
-
- QDBusPendingCallWatcher *watcher =
- new QDBusPendingCallWatcher(
- mPriv->baseInterface->HoldHandles(handleType, notYetHeld),
- pending);
-
- pending->connect(watcher,
- SIGNAL(finished(QDBusPendingCallWatcher *)),
- SLOT(onCallFinished(QDBusPendingCallWatcher *)));
- }
- else {
- debug() << " All handles already held, not calling HoldHandles";
- }
-
+ new PendingHandles(this, handleType, handles,
+ alreadyHeld, notYetHeld);
return pending;
}
diff --git a/TelepathyQt4/Client/pending-handles.cpp b/TelepathyQt4/Client/pending-handles.cpp
index 7100736..af4b9ab 100644
--- a/TelepathyQt4/Client/pending-handles.cpp
+++ b/TelepathyQt4/Client/pending-handles.cpp
@@ -42,6 +42,14 @@ struct PendingHandles::Private
UIntList handlesToReference;
ReferencedHandles handles;
ReferencedHandles alreadyHeld;
+
+ QStringList validNames;
+ QHash<QString, QPair<QString, QString> > invalidNames;
+
+ // one to one requests (ids)
+ QHash<QDBusPendingCallWatcher *, QString> idsForWatchers;
+ QHash<QString, uint> handlesForIds;
+ int requests;
};
PendingHandles::PendingHandles(Connection* connection, uint handleType, const QStringList& names)
@@ -53,9 +61,21 @@ PendingHandles::PendingHandles(Connection* connection, uint handleType, const QS
mPriv->handleType = handleType;
mPriv->isRequest = true;
mPriv->namesRequested = names;
+ mPriv->requests = 0;
+
+ // try to request all handles at once
+ QDBusPendingCallWatcher *watcher =
+ new QDBusPendingCallWatcher(
+ connection->baseInterface()->RequestHandles(handleType, names),
+ this);
+ connect(watcher,
+ SIGNAL(finished(QDBusPendingCallWatcher *)),
+ SLOT(onCallFinished(QDBusPendingCallWatcher *)));
}
-PendingHandles::PendingHandles(Connection* connection, uint handleType, const UIntList& handles, const UIntList& alreadyHeld)
+PendingHandles::PendingHandles(Connection *connection, uint handleType,
+ const UIntList &handles, const UIntList &alreadyHeld,
+ const UIntList ¬YetHeld)
: PendingOperation(connection), mPriv(new Private)
{
debug() << "PendingHandles(reference)";
@@ -65,11 +85,22 @@ PendingHandles::PendingHandles(Connection* connection, uint handleType, const UI
mPriv->isRequest = false;
mPriv->handlesToReference = handles;
mPriv->alreadyHeld = ReferencedHandles(connection, handleType, alreadyHeld);
+ mPriv->requests = 0;
- if (alreadyHeld == handles) {
+ if (notYetHeld.isEmpty()) {
debug() << " All handles already held, finishing up instantly";
mPriv->handles = mPriv->alreadyHeld;
setFinished();
+ } else {
+ debug() << " Calling HoldHandles";
+
+ QDBusPendingCallWatcher *watcher =
+ new QDBusPendingCallWatcher(
+ connection->baseInterface()->HoldHandles(handleType, notYetHeld),
+ this);
+ connect(watcher,
+ SIGNAL(finished(QDBusPendingCallWatcher *)),
+ SLOT(onCallFinished(QDBusPendingCallWatcher *)));
}
}
@@ -103,6 +134,32 @@ const QStringList& PendingHandles::namesRequested() const
return mPriv->namesRequested;
}
+QStringList PendingHandles::validNames() const
+{
+ if (!isFinished()) {
+ warning() << "PendingHandles::validNames called before finished";
+ return QStringList();
+ } else if (!isValid()) {
+ warning() << "PendingHandles::validNames called when not valid";
+ return QStringList();
+ }
+
+ return mPriv->validNames;
+}
+
+QHash<QString, QPair<QString, QString> > PendingHandles::invalidNames() const
+{
+ if (!isFinished()) {
+ warning() << "PendingHandles::invalidNames called before finished";
+ return QHash<QString, QPair<QString, QString> >();
+ } else if (!isValid()) {
+ warning() << "PendingHandles::invalidNames called when not valid";
+ return QHash<QString, QPair<QString, QString> >();
+ }
+
+ return mPriv->invalidNames;
+}
+
const UIntList& PendingHandles::handlesToReference() const
{
return mPriv->handlesToReference;
@@ -119,17 +176,41 @@ void PendingHandles::onCallFinished(QDBusPendingCallWatcher* watcher)
if (mPriv->isRequest) {
QDBusPendingReply<UIntList> reply = *watcher;
- debug() << "Received reply to RequestHandles";
-
if (reply.isError()) {
- debug().nospace() << " Failure: error " << reply.error().name() << ": " << reply.error().message();
- setFinishedWithError(reply.error());
+ if (mPriv->namesRequested.size() == 1) {
+ debug().nospace() << " Failure: error " <<
+ reply.error().name() << ": " <<
+ reply.error().message();
+
+ mPriv->invalidNames.insert(mPriv->namesRequested.first(),
+ QPair<QString, QString>(reply.error().name(),
+ reply.error().message()));
+ setFinishedWithError(reply.error());
+ connection()->handleRequestLanded(mPriv->handleType);
+ return;
+ }
+
+ // try to request one handles at a time
+ foreach (const QString &name, mPriv->namesRequested) {
+ QDBusPendingCallWatcher *watcher =
+ new QDBusPendingCallWatcher(
+ mPriv->connection->baseInterface()->RequestHandles(
+ mPriv->handleType,
+ QStringList() << name),
+ this);
+ connect(watcher,
+ SIGNAL(finished(QDBusPendingCallWatcher *)),
+ SLOT(onRequestHandlesFinished(QDBusPendingCallWatcher *)));
+ mPriv->idsForWatchers.insert(watcher, name);
+ }
} else {
- mPriv->handles = ReferencedHandles(connection(), handleType(), reply.value());
+ debug() << "Received reply to RequestHandles";
+ mPriv->handles = ReferencedHandles(connection(),
+ mPriv->handleType, reply.value());
+ mPriv->validNames.append(mPriv->namesRequested);
setFinished();
+ connection()->handleRequestLanded(mPriv->handleType);
}
-
- connection()->handleRequestLanded(handleType());
} else {
QDBusPendingReply<void> reply = *watcher;
@@ -139,7 +220,8 @@ void PendingHandles::onCallFinished(QDBusPendingCallWatcher* watcher)
debug().nospace() << " Failure: error " << reply.error().name() << ": " << reply.error().message();
setFinishedWithError(reply.error());
} else {
- mPriv->handles = ReferencedHandles(connection(), handleType(), handlesToReference());
+ mPriv->handles = ReferencedHandles(connection(),
+ mPriv->handleType, handlesToReference());
setFinished();
}
}
@@ -147,5 +229,58 @@ void PendingHandles::onCallFinished(QDBusPendingCallWatcher* watcher)
watcher->deleteLater();
}
+void PendingHandles::onRequestHandlesFinished(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<UIntList> reply = *watcher;
+
+ Q_ASSERT(mPriv->idsForWatchers.contains(watcher));
+ QString id = mPriv->idsForWatchers.value(watcher);
+
+ debug() << "Received reply to RequestHandles(" << id << ")";
+
+ if (reply.isError()) {
+ debug().nospace() << " Failure: error " << reply.error().name() << ": "
+ << reply.error().message();
+ mPriv->invalidNames.insert(id,
+ QPair<QString, QString>(reply.error().name(),
+ reply.error().message()));
+ } else {
+ Q_ASSERT(reply.value().size() == 1);
+ uint handle = reply.value().first();
+ mPriv->handlesForIds.insert(id, handle);
+ }
+
+ if (++mPriv->requests == mPriv->namesRequested.size()) {
+ if (mPriv->handlesForIds.size() == 0) {
+ // all requests failed
+ setFinishedWithError(reply.error());
+ } else {
+ // all requests either failed or finished successfully
+
+ // we need to return the handles in the same order as requested
+ UIntList handles;
+ foreach (const QString &name, mPriv->namesRequested) {
+ if (!mPriv->invalidNames.contains(name)) {
+ Q_ASSERT(mPriv->handlesForIds.contains(name));
+ handles.append(mPriv->handlesForIds.value(name));
+ mPriv->validNames.append(name);
+ }
+ }
+ mPriv->handles = ReferencedHandles(connection(),
+ mPriv->handleType, handles);
+
+ setFinished();
+ }
+
+ debug() << " namesRequested:" << mPriv->namesRequested;
+ debug() << " invalidNames :" << mPriv->invalidNames;
+ debug() << " validNames :" << mPriv->validNames;
+
+ connection()->handleRequestLanded(handleType());
+ }
+
+ watcher->deleteLater();
+}
+
} // Telepathy::Client
} // Telepathy
diff --git a/TelepathyQt4/Client/pending-handles.h b/TelepathyQt4/Client/pending-handles.h
index ec32955..f73e81e 100644
--- a/TelepathyQt4/Client/pending-handles.h
+++ b/TelepathyQt4/Client/pending-handles.h
@@ -131,6 +131,10 @@ public:
*/
const QStringList& namesRequested() const;
+ QStringList validNames() const;
+
+ QHash<QString, QPair<QString, QString> > invalidNames() const;
+
/**
* If the operation was a reference (as returned by isReference()), returns
* the handles which were to be referenced. Otherwise, returns an empty
@@ -156,12 +160,14 @@ public:
private Q_SLOTS:
void onCallFinished(QDBusPendingCallWatcher* watcher);
+ void onRequestHandlesFinished(QDBusPendingCallWatcher *watcher);
private:
friend class Connection;
PendingHandles(Connection* connection, uint handleType, const QStringList& names);
- PendingHandles(Connection* connection, uint handleType, const UIntList& handles, const UIntList& alreadyHeld);
+ PendingHandles(Connection *connection, uint handleType, const UIntList &handles,
+ const UIntList &alreadyHeld, const UIntList ¬YetHeld);
struct Private;
friend struct Private;
diff --git a/tests/dbus/contacts.cpp b/tests/dbus/contacts.cpp
index aa1e57c..205989d 100644
--- a/tests/dbus/contacts.cpp
+++ b/tests/dbus/contacts.cpp
@@ -340,12 +340,12 @@ void TestContacts::testForIdentifiers()
SLOT(expectSuccessfulCall(Telepathy::Client::PendingOperation*))));
QCOMPARE(mLoop->exec(), 1);
- // A request with both valid and invalid IDs should also fail
+ // A request with both valid and invalid IDs should succeed
fails = mConn->contactManager()->contactsForIdentifiers(invalidIDs + validIDs + invalidIDs);
QVERIFY(connect(fails,
SIGNAL(finished(Telepathy::Client::PendingOperation*)),
SLOT(expectSuccessfulCall(Telepathy::Client::PendingOperation*))));
- QCOMPARE(mLoop->exec(), 1);
+ QCOMPARE(mLoop->exec(), 0);
// Go on to the meat: valid IDs
PendingContacts *pending = mConn->contactManager()->contactsForIdentifiers(validIDs);
--
1.5.6.5
More information about the telepathy-commits
mailing list