src/network/access/qhttpnetworkconnection.cpp
branchRCL_3
changeset 14 c0432d11811c
parent 8 3f74d0d4af4c
equal deleted inserted replaced
13:cc75c76972ee 14:c0432d11811c
    69 const int QHttpNetworkConnectionPrivate::defaultChannelCount = 3;
    69 const int QHttpNetworkConnectionPrivate::defaultChannelCount = 3;
    70 #else
    70 #else
    71 const int QHttpNetworkConnectionPrivate::defaultChannelCount = 6;
    71 const int QHttpNetworkConnectionPrivate::defaultChannelCount = 6;
    72 #endif
    72 #endif
    73 
    73 
    74 // the maximum amount of requests that might be pipelined into a socket
    74 // The pipeline length. So there will be 4 requests in flight.
    75 // from what was suggested, 3 seems to be OK
       
    76 const int QHttpNetworkConnectionPrivate::defaultPipelineLength = 3;
    75 const int QHttpNetworkConnectionPrivate::defaultPipelineLength = 3;
       
    76 // Only re-fill the pipeline if there's defaultRePipelineLength slots free in the pipeline.
       
    77 // This means that there are 2 requests in flight and 2 slots free that will be re-filled.
       
    78 const int QHttpNetworkConnectionPrivate::defaultRePipelineLength = 2;
    77 
    79 
    78 
    80 
    79 QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt)
    81 QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt)
    80 : hostName(hostName), port(port), encrypt(encrypt),
    82 : hostName(hostName), port(port), encrypt(encrypt),
    81   channelCount(defaultChannelCount),
    83   channelCount(defaultChannelCount),
   485     if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
   487     if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
   486         return;
   488         return;
   487 
   489 
   488     int i = indexOf(socket);
   490     int i = indexOf(socket);
   489 
   491 
   490     bool highPriorityQueueProcessingDone = false;
   492     // return fast if there was no reply right now processed
   491     bool lowPriorityQueueProcessingDone = false;
   493     if (channels[i].reply == 0)
   492 
   494         return;
   493     while (!highPriorityQueueProcessingDone && !lowPriorityQueueProcessingDone) {
   495 
   494         // this loop runs once per request we intend to pipeline in.
   496     if (! (defaultPipelineLength - channels[i].alreadyPipelinedRequests.length() >= defaultRePipelineLength)) {
   495 
   497         return;
   496         if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported)
   498     }
   497             return;
   499 
   498 
   500     if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported)
   499         // the current request that is in must already support pipelining
   501         return;
   500         if (!channels[i].request.isPipeliningAllowed())
   502 
   501             return;
   503     // the current request that is in must already support pipelining
   502 
   504     if (!channels[i].request.isPipeliningAllowed())
   503         // the current request must be a idempotent (right now we only check GET)
   505         return;
   504         if (channels[i].request.operation() != QHttpNetworkRequest::Get)
   506 
   505             return;
   507     // the current request must be a idempotent (right now we only check GET)
   506 
   508     if (channels[i].request.operation() != QHttpNetworkRequest::Get)
   507         // check if socket is connected
   509         return;
   508         if (socket->state() != QAbstractSocket::ConnectedState)
   510 
   509             return;
   511     // check if socket is connected
   510 
   512     if (socket->state() != QAbstractSocket::ConnectedState)
   511         // check for resendCurrent
   513         return;
   512         if (channels[i].resendCurrent)
   514 
   513             return;
   515     // check for resendCurrent
   514 
   516     if (channels[i].resendCurrent)
   515         // we do not like authentication stuff
   517         return;
   516         // ### make sure to be OK with this in later releases
   518 
   517         if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty())
   519     // we do not like authentication stuff
   518             return;
   520     // ### make sure to be OK with this in later releases
   519         if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty())
   521     if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty())
   520             return;
   522         return;
   521 
   523     if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty())
   522         // check for pipeline length
   524         return;
       
   525 
       
   526     // must be in ReadingState or WaitingState
       
   527     if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState
       
   528            || channels[i].state == QHttpNetworkConnectionChannel::ReadingState))
       
   529         return;
       
   530 
       
   531 
       
   532     //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing highPriorityQueue, size=" << highPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length();
       
   533     int lengthBefore;
       
   534     while (!highPriorityQueue.isEmpty()) {
       
   535         lengthBefore = channels[i].alreadyPipelinedRequests.length();
       
   536         fillPipeline(highPriorityQueue, channels[i]);
       
   537 
   523         if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
   538         if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
   524             return;
   539             return;
   525 
   540 
   526         // must be in ReadingState or WaitingState
   541         if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
   527         if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState
   542             break; // did not process anything, now do the low prio queue
   528                || channels[i].state == QHttpNetworkConnectionChannel::ReadingState))
   543     }
       
   544 
       
   545     //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing lowPriorityQueue, size=" << lowPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length();
       
   546     while (!lowPriorityQueue.isEmpty()) {
       
   547         lengthBefore = channels[i].alreadyPipelinedRequests.length();
       
   548         fillPipeline(lowPriorityQueue, channels[i]);
       
   549 
       
   550         if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
   529             return;
   551             return;
   530 
   552 
   531         highPriorityQueueProcessingDone = fillPipeline(highPriorityQueue, channels[i]);
   553         if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
   532         // not finished with highPriorityQueue? then loop again
   554             break; // did not process anything
   533         if (!highPriorityQueueProcessingDone)
   555     }
   534             continue;
   556 
   535         // highPriorityQueue was processed, now deal with the lowPriorityQueue
   557 
   536         lowPriorityQueueProcessingDone = fillPipeline(lowPriorityQueue, channels[i]);
       
   537     }
       
   538 }
   558 }
   539 
   559 
   540 // returns true when the processing of a queue has been done
   560 // returns true when the processing of a queue has been done
   541 bool QHttpNetworkConnectionPrivate::fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel)
   561 bool QHttpNetworkConnectionPrivate::fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel)
   542 {
   562 {
   705             channels[i].state = QHttpNetworkConnectionChannel::IdleState;
   725             channels[i].state = QHttpNetworkConnectionChannel::IdleState;
   706 
   726 
   707             // if this is not possible, error will be emitted and connection terminated
   727             // if this is not possible, error will be emitted and connection terminated
   708             if (!channels[i].resetUploadData())
   728             if (!channels[i].resetUploadData())
   709                 continue;
   729                 continue;
   710 
       
   711             channels[i].sendRequest();
   730             channels[i].sendRequest();
   712         }
   731         }
   713     }
   732     }
   714 
   733 
   715     // dequeue new ones
   734     // dequeue new ones
   745     // on the connected sockets
   764     // on the connected sockets
   746     //tryToFillPipeline(socket);
   765     //tryToFillPipeline(socket);
   747     // return fast if there is nothing to pipeline
   766     // return fast if there is nothing to pipeline
   748     if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
   767     if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
   749         return;
   768         return;
   750     for (int j = 0; j < channelCount; j++)
   769     for (int i = 0; i < channelCount; i++)
   751         fillPipeline(channels[j].socket);
   770         if (channels[i].socket->state() == QAbstractSocket::ConnectedState)
       
   771             fillPipeline(channels[i].socket);
   752 }
   772 }
   753 
   773 
   754 void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests()
   774 void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests()
   755 {
   775 {
   756     // send the request using the idle socket
   776     // send the request using the idle socket