From ebd683a4589e34ae4f142bc6ac64ae2b563d78fa Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Fri, 27 Aug 2021 22:08:11 +0200 Subject: QXmppStream: Refactor and simplify IQ handling --- src/base/QXmppStream.cpp | 82 ++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 52 deletions(-) (limited to 'src/base/QXmppStream.cpp') diff --git a/src/base/QXmppStream.cpp b/src/base/QXmppStream.cpp index 704fc2fb..28a26963 100644 --- a/src/base/QXmppStream.cpp +++ b/src/base/QXmppStream.cpp @@ -25,6 +25,7 @@ #include "QXmppStream.h" #include "QXmppConstants_p.h" +#include "QXmppFutureUtils_p.h" #include "QXmppIq.h" #include "QXmppLogger.h" #include "QXmppPacket_p.h" @@ -45,48 +46,13 @@ #include #include +using namespace QXmpp::Private; + #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) static bool randomSeeded = false; #endif -class IqState : public QFutureInterface -{ - Q_DISABLE_COPY(IqState) - -public: - IqState(QFuture sendFuture, bool streamManagementUsed, QObject *parent) - : QFutureInterface(QFutureInterfaceBase::Started), - m_sendFuture(std::move(sendFuture)), - m_streamManagementUsed(streamManagementUsed) - { - auto *watcher = new QFutureWatcher(parent); - QObject::connect(watcher, &QFutureWatcher::finished, [=]() { - const auto result = watcher->future().results().last(); - - switch (result) { - case QXmpp::Acknowledged: - case QXmpp::Sent: - break; - case QXmpp::NotSent: - reportResult(result); - reportFinished(); - break; - } - - watcher->deleteLater(); - }); - watcher->setFuture(m_sendFuture); - } - - bool isStreamManagementUsed() const - { - return m_streamManagementUsed; - } - -private: - QFuture m_sendFuture; - bool m_streamManagementUsed; -}; +using IqState = QFutureInterface; class QXmppStreamPrivate { @@ -103,7 +69,7 @@ public: QXmppStreamManager streamManager; // iq response handling - QMap runningIqs; + QMap runningIqs; }; QXmppStreamPrivate::QXmppStreamPrivate(QXmppStream *stream) @@ -254,13 +220,28 @@ QFuture QXmppStream::sendIq(const QXmppIq &iq) return sendIq(newIq); } - auto *interface = new IqState(send(iq), d->streamManager.enabled(), this); - - if (!interface->isFinished()) { - d->runningIqs.insert(iq.id(), interface); + auto sendFuture = send(iq); + if (sendFuture.isFinished()) { + if (sendFuture.result() == QXmpp::NotSent) { + // early exit (saves QFutureWatcher) + return makeReadyFuture(QXmpp::NotSent); + } + } else { + awaitLast(sendFuture, this, [this, id = iq.id()](QXmpp::PacketState result) { + if (result == QXmpp::NotSent) { + if (auto itr = d->runningIqs.find(id); itr != d->runningIqs.end()) { + itr.value().reportResult(QXmpp::NotSent); + itr.value().reportFinished(); + + d->runningIqs.erase(itr); + } + } + }); } - return interface->future(); + IqState interface(IqState::Started); + d->runningIqs.insert(iq.id(), interface); + return interface.future(); } /// @@ -270,10 +251,9 @@ QFuture QXmppStream::sendIq(const QXmppIq &iq) /// void QXmppStream::cancelOngoingIqs() { - for (auto *state : std::as_const(d->runningIqs)) { - state->reportResult(QXmpp::NotSent); - state->reportFinished(); - delete state; + for (auto &state : d->runningIqs) { + state.reportResult(QXmpp::NotSent); + state.reportFinished(); } d->runningIqs.clear(); } @@ -471,10 +451,8 @@ bool QXmppStream::handleIqResponse(const QDomElement &stanza) if (auto itr = d->runningIqs.find(stanza.attribute(QStringLiteral("id"))); itr != d->runningIqs.end()) { - auto *state = itr.value(); - state->reportResult(stanza); - state->reportFinished(); - delete state; + itr.value().reportResult(stanza); + itr.value().reportFinished(); d->runningIqs.erase(itr); return true; -- cgit v1.2.3