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 { |
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 |