QNetworkReply: replace a QQueue with a std::vector

The 'queue' was never used as a queue: it was populated, and then
exchanged into a local copy to be consumed in a loop. This loop used
dequeue(), but of course it could just const-iterate the container and
dump it as the end, since the member variable was already reset at
that point, no-one could tell the difference from the outside.

So, no need for a queue. A vector will do very nicely.

The loop now uses ranged-for and qExchange(), greatly simplifying the
code over the old version.

Add another qExchange() call as a drive-by.

Change-Id: I6147453dc9edfe9500833627b123bb3a31114651
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Marc Mutz 2019-05-13 20:49:57 +02:00
parent c871ba2b23
commit 8b771e782d
2 changed files with 9 additions and 16 deletions

View File

@ -158,7 +158,7 @@ void QNetworkReplyImplPrivate::_q_startOperation()
} else {
if (state != Finished) {
if (operation == QNetworkAccessManager::GetOperation)
pendingNotifications.append(NotifyDownstreamReadyWrite);
pendingNotifications.push_back(NotifyDownstreamReadyWrite);
handleNotifications();
}
@ -433,8 +433,9 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const
void QNetworkReplyImplPrivate::backendNotify(InternalNotifications notification)
{
Q_Q(QNetworkReplyImpl);
if (!pendingNotifications.contains(notification))
pendingNotifications.enqueue(notification);
const auto it = std::find(pendingNotifications.cbegin(), pendingNotifications.cend(), notification);
if (it == pendingNotifications.cend())
pendingNotifications.push_back(notification);
if (pendingNotifications.size() == 1)
QCoreApplication::postEvent(q, new QEvent(QEvent::NetworkReplyUpdated));
@ -445,14 +446,9 @@ void QNetworkReplyImplPrivate::handleNotifications()
if (notificationHandlingPaused)
return;
NotificationQueue current = pendingNotifications;
pendingNotifications.clear();
if (state != Working)
return;
while (state == Working && !current.isEmpty()) {
InternalNotifications notification = current.dequeue();
for (InternalNotifications notification : qExchange(pendingNotifications, {})) {
if (state != Working)
return;
switch (notification) {
case NotifyDownstreamReadyWrite:
if (copyDevice)
@ -466,8 +462,7 @@ void QNetworkReplyImplPrivate::handleNotifications()
break;
case NotifyCopyFinished: {
QIODevice *dev = copyDevice;
copyDevice = 0;
QIODevice *dev = qExchange(copyDevice, nullptr);
backend->copyFinished(dev);
break;
}

View File

@ -117,8 +117,6 @@ public:
NotifyCopyFinished
};
typedef QQueue<InternalNotifications> NotificationQueue;
QNetworkReplyImplPrivate();
void _q_startOperation();
@ -178,7 +176,7 @@ public:
bool cacheEnabled;
QIODevice *cacheSaveDevice;
NotificationQueue pendingNotifications;
std::vector<InternalNotifications> pendingNotifications;
bool notificationHandlingPaused;
QUrl urlForLastAuthentication;