[Telepathy-commits] [telepathy-qt4/master] PendingHandles: Added fallback for HoldHandles.
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Wed Mar 25 10:17:20 PDT 2009
Fallback to one to one handle when HoldHandles fail.
---
TelepathyQt4/Client/pending-handles.cpp | 96 ++++++++++++++++++++++++++++++-
TelepathyQt4/Client/pending-handles.h | 3 +
2 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/TelepathyQt4/Client/pending-handles.cpp b/TelepathyQt4/Client/pending-handles.cpp
index c2b2f0b..07f0431 100644
--- a/TelepathyQt4/Client/pending-handles.cpp
+++ b/TelepathyQt4/Client/pending-handles.cpp
@@ -53,11 +53,12 @@ struct PendingHandles::Private
UIntList handlesToReference;
ReferencedHandles handles;
ReferencedHandles alreadyHeld;
-
+ UIntList invalidHandles;
QStringList validNames;
QHash<QString, QPair<QString, QString> > invalidNames;
// one to one requests (ids)
+ QHash<QDBusPendingCallWatcher *, uint> handlesForWatchers;
QHash<QDBusPendingCallWatcher *, QString> idsForWatchers;
QHash<QString, uint> handlesForIds;
int requestsFinished;
@@ -255,6 +256,15 @@ ReferencedHandles PendingHandles::handles() const
return mPriv->handles;
}
+UIntList PendingHandles::invalidHandles() const
+{
+ if (!isFinished()) {
+ warning() << "PendingHandles::invalidHandles called before finished";
+ }
+
+ return mPriv->invalidHandles;
+}
+
void PendingHandles::onRequestHandlesFinished(QDBusPendingCallWatcher *watcher)
{
QDBusPendingReply<UIntList> reply = *watcher;
@@ -323,7 +333,42 @@ void PendingHandles::onHoldHandlesFinished(QDBusPendingCallWatcher *watcher)
debug().nospace() << " Failure: error " <<
reply.error().name() << ": " <<
reply.error().message();
- setFinishedWithError(reply.error());
+
+ QDBusError error = reply.error();
+ if (error.name() != TELEPATHY_ERROR_INVALID_HANDLE &&
+ error.name() != TELEPATHY_ERROR_INVALID_ARGUMENT &&
+ error.name() != TELEPATHY_ERROR_NOT_AVAILABLE) {
+ // do not fallback
+ mPriv->invalidHandles = mPriv->handlesToReference;
+ setFinishedWithError(error);
+ watcher->deleteLater();
+ return;
+ }
+
+ if (mPriv->handlesToReference.size() == 1) {
+ debug().nospace() << " Failure: error " <<
+ reply.error().name() << ": " <<
+ reply.error().message();
+
+ mPriv->invalidHandles = mPriv->handlesToReference;
+ setFinished();
+ watcher->deleteLater();
+ return;
+ }
+
+ // try to request one handles at a time
+ foreach (uint handle, mPriv->handlesToReference) {
+ QDBusPendingCallWatcher *watcher =
+ new QDBusPendingCallWatcher(
+ mPriv->connection->baseInterface()->HoldHandles(
+ mPriv->handleType,
+ UIntList() << handle),
+ this);
+ connect(watcher,
+ SIGNAL(finished(QDBusPendingCallWatcher *)),
+ SLOT(onHoldHandlesFallbackFinished(QDBusPendingCallWatcher *)));
+ mPriv->handlesForWatchers.insert(watcher, handle);
+ }
} else {
mPriv->handles = ReferencedHandles(mPriv->connection,
mPriv->handleType, mPriv->handlesToReference);
@@ -403,5 +448,52 @@ void PendingHandles::onRequestHandlesFallbackFinished(QDBusPendingCallWatcher *w
watcher->deleteLater();
}
+void PendingHandles::onHoldHandlesFallbackFinished(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<void> reply = *watcher;
+
+ Q_ASSERT(mPriv->handlesForWatchers.contains(watcher));
+ uint handle = mPriv->handlesForWatchers.value(watcher);
+
+ debug() << "Received reply to HoldHandles(" << handle << ")";
+
+ if (reply.isError()) {
+ debug().nospace() << " Failure: error " << reply.error().name() << ": "
+ << reply.error().message();
+
+ // if the error is disconnected for example, fail immediately
+ QDBusError error = reply.error();
+ if (error.name() != TELEPATHY_ERROR_INVALID_HANDLE &&
+ error.name() != TELEPATHY_ERROR_INVALID_ARGUMENT &&
+ error.name() != TELEPATHY_ERROR_NOT_AVAILABLE) {
+ mPriv->invalidHandles = mPriv->handlesToReference;
+ setFinishedWithError(error);
+ watcher->deleteLater();
+ return;
+ }
+
+ mPriv->invalidHandles.append(handle);
+ }
+
+ if (++mPriv->requestsFinished == mPriv->namesRequested.size()) {
+ // we need to return the handles in the same order as requested
+ UIntList handles;
+ foreach (uint handle, mPriv->handlesToReference) {
+ if (!mPriv->invalidHandles.contains(handle)) {
+ handles.append(handle);
+ }
+ }
+
+ if (handles.size() != 0) {
+ mPriv->handles = ReferencedHandles(mPriv->connection,
+ mPriv->handleType, handles);
+ }
+
+ setFinished();
+ }
+
+ watcher->deleteLater();
+}
+
} // Telepathy::Client
} // Telepathy
diff --git a/TelepathyQt4/Client/pending-handles.h b/TelepathyQt4/Client/pending-handles.h
index e91d21f..1af55dd 100644
--- a/TelepathyQt4/Client/pending-handles.h
+++ b/TelepathyQt4/Client/pending-handles.h
@@ -70,10 +70,13 @@ public:
ReferencedHandles handles() const;
+ UIntList invalidHandles() const;
+
private Q_SLOTS:
void onRequestHandlesFinished(QDBusPendingCallWatcher *watcher);
void onHoldHandlesFinished(QDBusPendingCallWatcher *watcher);
void onRequestHandlesFallbackFinished(QDBusPendingCallWatcher *watcher);
+ void onHoldHandlesFallbackFinished(QDBusPendingCallWatcher *watcher);
private:
friend class Connection;
--
1.5.6.5
More information about the telepathy-commits
mailing list