src/network/access/qhttpnetworkconnection.cpp
changeset 22 79de32ba3296
parent 19 fcece45ef507
child 23 89e065397ea6
equal deleted inserted replaced
19:fcece45ef507 22:79de32ba3296
    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     if (! (defaultPipelineLength - channels[i].alreadyPipelinedRequests.length() >= 2)) {
   491     bool lowPriorityQueueProcessingDone = false;
   493         return;
   492 
   494     }
   493     while (!highPriorityQueueProcessingDone && !lowPriorityQueueProcessingDone) {
   495 
   494         // this loop runs once per request we intend to pipeline in.
   496     if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported)
   495 
   497         return;
   496         if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported)
   498 
   497             return;
   499     // the current request that is in must already support pipelining
   498 
   500     if (!channels[i].request.isPipeliningAllowed())
   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 must be a idempotent (right now we only check GET)
   502 
   504     if (channels[i].request.operation() != QHttpNetworkRequest::Get)
   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     // check if socket is connected
   506 
   508     if (socket->state() != QAbstractSocket::ConnectedState)
   507         // check if socket is connected
   509         return;
   508         if (socket->state() != QAbstractSocket::ConnectedState)
   510 
   509             return;
   511     // check for resendCurrent
   510 
   512     if (channels[i].resendCurrent)
   511         // check for resendCurrent
   513         return;
   512         if (channels[i].resendCurrent)
   514 
   513             return;
   515     // we do not like authentication stuff
   514 
   516     // ### make sure to be OK with this in later releases
   515         // we do not like authentication stuff
   517     if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty())
   516         // ### make sure to be OK with this in later releases
   518         return;
   517         if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty())
   519     if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty())
   518             return;
   520         return;
   519         if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty())
   521 
   520             return;
   522     // must be in ReadingState or WaitingState
   521 
   523     if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState
   522         // check for pipeline length
   524            || channels[i].state == QHttpNetworkConnectionChannel::ReadingState))
       
   525         return;
       
   526 
       
   527 
       
   528     //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing highPriorityQueue, size=" << highPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length();
       
   529     int lengthBefore;
       
   530     while (!highPriorityQueue.isEmpty()) {
       
   531         lengthBefore = channels[i].alreadyPipelinedRequests.length();
       
   532         fillPipeline(highPriorityQueue, channels[i]);
       
   533 
   523         if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
   534         if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
   524             return;
   535             return;
   525 
   536 
   526         // must be in ReadingState or WaitingState
   537         if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
   527         if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState
   538             break; // did not process anything, now do the low prio queue
   528                || channels[i].state == QHttpNetworkConnectionChannel::ReadingState))
   539     }
       
   540 
       
   541     //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing lowPriorityQueue, size=" << lowPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length();
       
   542     while (!lowPriorityQueue.isEmpty()) {
       
   543         lengthBefore = channels[i].alreadyPipelinedRequests.length();
       
   544         fillPipeline(lowPriorityQueue, channels[i]);
       
   545 
       
   546         if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength)
   529             return;
   547             return;
   530 
   548 
   531         highPriorityQueueProcessingDone = fillPipeline(highPriorityQueue, channels[i]);
   549         if (lengthBefore == channels[i].alreadyPipelinedRequests.length())
   532         // not finished with highPriorityQueue? then loop again
   550             break; // did not process anything
   533         if (!highPriorityQueueProcessingDone)
   551     }
   534             continue;
   552 
   535         // highPriorityQueue was processed, now deal with the lowPriorityQueue
   553 
   536         lowPriorityQueueProcessingDone = fillPipeline(lowPriorityQueue, channels[i]);
       
   537     }
       
   538 }
   554 }
   539 
   555 
   540 // returns true when the processing of a queue has been done
   556 // returns true when the processing of a queue has been done
   541 bool QHttpNetworkConnectionPrivate::fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel)
   557 bool QHttpNetworkConnectionPrivate::fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel)
   542 {
   558 {
   705             channels[i].state = QHttpNetworkConnectionChannel::IdleState;
   721             channels[i].state = QHttpNetworkConnectionChannel::IdleState;
   706 
   722 
   707             // if this is not possible, error will be emitted and connection terminated
   723             // if this is not possible, error will be emitted and connection terminated
   708             if (!channels[i].resetUploadData())
   724             if (!channels[i].resetUploadData())
   709                 continue;
   725                 continue;
   710 
       
   711             channels[i].sendRequest();
   726             channels[i].sendRequest();
   712         }
   727         }
   713     }
   728     }
   714 
   729 
   715     // dequeue new ones
   730     // dequeue new ones
   745     // on the connected sockets
   760     // on the connected sockets
   746     //tryToFillPipeline(socket);
   761     //tryToFillPipeline(socket);
   747     // return fast if there is nothing to pipeline
   762     // return fast if there is nothing to pipeline
   748     if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
   763     if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
   749         return;
   764         return;
   750     for (int j = 0; j < channelCount; j++)
   765     for (int i = 0; i < channelCount; i++)
   751         fillPipeline(channels[j].socket);
   766         if (channels[i].socket->state() == QAbstractSocket::ConnectedState)
       
   767             fillPipeline(channels[i].socket);
   752 }
   768 }
   753 
   769 
   754 void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests()
   770 void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests()
   755 {
   771 {
   756     // send the request using the idle socket
   772     // send the request using the idle socket