From c68737add39360040e5b0cd93f01f229d6a8bbc9 Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Thu, 1 Mar 2012 10:36:38 +0100 Subject: QNam: only init channels when needed. Each channel will create a socket that will allocate memory for the read and write buffers. This change will instead initialize channels only when they are needed. Change-Id: I112b4c7b944a7dd345414f06260c92803394eaed Reviewed-by: Shane Kearns --- src/network/access/qhttpnetworkconnection.cpp | 108 +++++++++++++++----------- 1 file changed, 63 insertions(+), 45 deletions(-) (limited to 'src/network/access/qhttpnetworkconnection.cpp') diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 6aa3a5a5f4..95b81c437d 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -123,8 +123,8 @@ void QHttpNetworkConnectionPrivate::init() //push session down to channels channels[i].networkSession = networkSession; #endif - channels[i].init(); } + delayedConnectionTimer.setSingleShot(true); QObject::connect(&delayedConnectionTimer, SIGNAL(timeout()), q, SLOT(_q_connectDelayedChannel())); } @@ -135,12 +135,14 @@ void QHttpNetworkConnectionPrivate::pauseConnection() // Disable all socket notifiers for (int i = 0; i < channelCount; i++) { + if (channels[i].socket) { #ifndef QT_NO_SSL - if (encrypt) - QSslSocketPrivate::pauseSocketNotifiers(static_cast(channels[i].socket)); - else + if (encrypt) + QSslSocketPrivate::pauseSocketNotifiers(static_cast(channels[i].socket)); + else #endif - QAbstractSocketPrivate::pauseSocketNotifiers(channels[i].socket); + QAbstractSocketPrivate::pauseSocketNotifiers(channels[i].socket); + } } } @@ -149,16 +151,18 @@ void QHttpNetworkConnectionPrivate::resumeConnection() state = RunningState; // Enable all socket notifiers for (int i = 0; i < channelCount; i++) { + if (channels[i].socket) { #ifndef QT_NO_SSL - if (encrypt) - QSslSocketPrivate::resumeSocketNotifiers(static_cast(channels[i].socket)); - else + if (encrypt) + QSslSocketPrivate::resumeSocketNotifiers(static_cast(channels[i].socket)); + else #endif - QAbstractSocketPrivate::resumeSocketNotifiers(channels[i].socket); + QAbstractSocketPrivate::resumeSocketNotifiers(channels[i].socket); - // Resume pending upload if needed - if (channels[i].state == QHttpNetworkConnectionChannel::WritingState) - QMetaObject::invokeMethod(&channels[i], "_q_uploadDataReadyRead", Qt::QueuedConnection); + // Resume pending upload if needed + if (channels[i].state == QHttpNetworkConnectionChannel::WritingState) + QMetaObject::invokeMethod(&channels[i], "_q_uploadDataReadyRead", Qt::QueuedConnection); + } } // queue _q_startNextRequest @@ -346,11 +350,15 @@ void QHttpNetworkConnectionPrivate::emitReplyError(QAbstractSocket *socket, QNetworkReply::NetworkError errorCode) { Q_Q(QHttpNetworkConnection); - if (socket && reply) { + + int i = 0; + if (socket) + i = indexOf(socket); + + if (reply) { // this error matters only to this reply reply->d_func()->errorString = errorDetail(errorCode, socket); emit reply->finishedWithError(errorCode, reply->d_func()->errorString); - int i = indexOf(socket); // remove the corrupt data if any reply->d_func()->eraseData(); @@ -358,7 +366,8 @@ void QHttpNetworkConnectionPrivate::emitReplyError(QAbstractSocket *socket, channels[i].close(); channels[i].reply = 0; channels[i].request = QHttpNetworkRequest(); - channels[i].requeueCurrentlyPipelinedRequests(); + if (socket) + channels[i].requeueCurrentlyPipelinedRequests(); // send the next request QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); @@ -582,9 +591,9 @@ void QHttpNetworkConnectionPrivate::requeueRequest(const HttpMessagePair &pair) bool QHttpNetworkConnectionPrivate::dequeueRequest(QAbstractSocket *socket) { - Q_ASSERT(socket); - - int i = indexOf(socket); + int i = 0; + if (socket) + i = indexOf(socket); if (!highPriorityQueue.isEmpty()) { // remove from queue before sendRequest! else we might pipeline the same request again @@ -740,15 +749,15 @@ bool QHttpNetworkConnectionPrivate::fillPipeline(QList &queue, } -QString QHttpNetworkConnectionPrivate::errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket* socket, - const QString &extraDetail) +QString QHttpNetworkConnectionPrivate::errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket, const QString &extraDetail) { - Q_ASSERT(socket); - QString errorString; switch (errorCode) { case QNetworkReply::HostNotFoundError: - errorString = QCoreApplication::translate("QHttp", "Host %1 not found").arg(socket->peerName()); + if (socket) + errorString = QCoreApplication::translate("QHttp", "Host %1 not found").arg(socket->peerName()); + else + errorString = QCoreApplication::translate("QHttp", "Host %1 not found").arg(hostName); break; case QNetworkReply::ConnectionRefusedError: errorString = QCoreApplication::translate("QHttp", "Connection refused"); @@ -891,9 +900,11 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() return; // try to get a free AND connected socket for (int i = 0; i < channelCount; ++i) { - if (!channels[i].reply && !channels[i].isSocketBusy() && channels[i].socket->state() == QAbstractSocket::ConnectedState) { - if (dequeueRequest(channels[i].socket)) - channels[i].sendRequest(); + if (channels[i].socket) { + if (!channels[i].reply && !channels[i].isSocketBusy() && channels[i].socket->state() == QAbstractSocket::ConnectedState) { + if (dequeueRequest(channels[i].socket)) + channels[i].sendRequest(); + } } } @@ -908,7 +919,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty()) return; for (int i = 0; i < channelCount; i++) - if (channels[i].socket->state() == QAbstractSocket::ConnectedState) + if (channels[i].socket && channels[i].socket->state() == QAbstractSocket::ConnectedState) fillPipeline(channels[i].socket); // If there is not already any connected channels we need to connect a new one. @@ -916,11 +927,19 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() // connected or not. This is to reuse connected channels before we connect new once. int queuedRequest = highPriorityQueue.count() + lowPriorityQueue.count(); for (int i = 0; i < channelCount; ++i) { - if ((channels[i].socket->state() == QAbstractSocket::ConnectingState) || (channels[i].socket->state() == QAbstractSocket::HostLookupState)) - queuedRequest--; - if ( queuedRequest <=0 ) - break; - if (!channels[i].reply && !channels[i].isSocketBusy() && (channels[i].socket->state() == QAbstractSocket::UnconnectedState)) { + bool connectChannel = false; + if (channels[i].socket) { + if ((channels[i].socket->state() == QAbstractSocket::ConnectingState) || (channels[i].socket->state() == QAbstractSocket::HostLookupState)) + queuedRequest--; + if ( queuedRequest <=0 ) + break; + if (!channels[i].reply && !channels[i].isSocketBusy() && (channels[i].socket->state() == QAbstractSocket::UnconnectedState)) + connectChannel = true; + } else { // not previously used channel + connectChannel = true; + } + + if (connectChannel) { if (networkLayerState == IPv4) channels[i].networkLayerPreference = QAbstractSocket::IPv4Protocol; else if (networkLayerState == IPv6) @@ -928,6 +947,9 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() channels[i].ensureConnection(); queuedRequest--; } + + if ( queuedRequest <=0 ) + break; } } @@ -958,8 +980,8 @@ void QHttpNetworkConnectionPrivate::startHostInfoLookup() #ifndef QT_NO_NETWORKPROXY if (networkProxy.capabilities() & QNetworkProxy::HostNameLookupCapability) { lookupHost = networkProxy.hostName(); - } else if (channels[0].socket->proxy().capabilities() & QNetworkProxy::HostNameLookupCapability) { - lookupHost = channels[0].socket->proxy().hostName(); + } else if (channels[0].proxy.capabilities() & QNetworkProxy::HostNameLookupCapability) { + lookupHost = channels[0].proxy.hostName(); } #endif QHostAddress temp; @@ -1169,13 +1191,13 @@ void QHttpNetworkConnection::setTransparentProxy(const QNetworkProxy &networkPro { Q_D(QHttpNetworkConnection); for (int i = 0; i < d->channelCount; ++i) - d->channels[i].socket->setProxy(networkProxy); + d->channels[i].setProxy(networkProxy); } QNetworkProxy QHttpNetworkConnection::transparentProxy() const { Q_D(const QHttpNetworkConnection); - return d->channels[0].socket->proxy(); + return d->channels[0].proxy; } #endif @@ -1190,7 +1212,7 @@ void QHttpNetworkConnection::setSslConfiguration(const QSslConfiguration &config // set the config on all channels for (int i = 0; i < d->channelCount; ++i) - static_cast(d->channels[i].socket)->setSslConfiguration(config); + d->channels[i].setSslConfiguration(config); } void QHttpNetworkConnection::ignoreSslErrors(int channel) @@ -1201,13 +1223,11 @@ void QHttpNetworkConnection::ignoreSslErrors(int channel) if (channel == -1) { // ignore for all channels for (int i = 0; i < d->channelCount; ++i) { - static_cast(d->channels[i].socket)->ignoreSslErrors(); - d->channels[i].ignoreAllSslErrors = true; + d->channels[i].ignoreSslErrors(); } } else { - static_cast(d->channels[channel].socket)->ignoreSslErrors(); - d->channels[channel].ignoreAllSslErrors = true; + d->channels[channel].ignoreSslErrors(); } } @@ -1219,13 +1239,11 @@ void QHttpNetworkConnection::ignoreSslErrors(const QList &errors, int if (channel == -1) { // ignore for all channels for (int i = 0; i < d->channelCount; ++i) { - static_cast(d->channels[i].socket)->ignoreSslErrors(errors); - d->channels[i].ignoreSslErrorsList = errors; + d->channels[i].ignoreSslErrors(errors); } } else { - static_cast(d->channels[channel].socket)->ignoreSslErrors(errors); - d->channels[channel].ignoreSslErrorsList = errors; + d->channels[channel].ignoreSslErrors(errors); } } -- cgit v1.2.3