| Index: net/quic/quic_session.cc
|
| diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc
|
| index 512044f9fb4e15b20751010060ff67fa004897f7..9b28103c8f9ed75d0a24f8e723829b7f02e7f412 100644
|
| --- a/net/quic/quic_session.cc
|
| +++ b/net/quic/quic_session.cc
|
| @@ -79,8 +79,8 @@ class VisitorShim : public QuicConnectionVisitorInterface {
|
| session_->OnWriteBlocked();
|
| }
|
|
|
| - virtual bool HasPendingWrites() const OVERRIDE {
|
| - return session_->HasPendingWrites();
|
| + virtual bool WillingAndAbleToWrite() const OVERRIDE {
|
| + return session_->WillingAndAbleToWrite();
|
| }
|
|
|
| virtual bool HasPendingHandshake() const OVERRIDE {
|
| @@ -275,9 +275,22 @@ void QuicSession::OnBlockedFrames(const vector<QuicBlockedFrame>& frames) {
|
|
|
| void QuicSession::OnCanWrite() {
|
| // We limit the number of writes to the number of pending streams. If more
|
| - // streams become pending, HasPendingWrites will be true, which will cause
|
| - // the connection to request resumption before yielding to other connections.
|
| + // streams become pending, WillingAndAbleToWrite will be true, which will
|
| + // cause the connection to request resumption before yielding to other
|
| + // connections.
|
| size_t num_writes = write_blocked_streams_.NumBlockedStreams();
|
| + if (flow_controller_->IsBlocked()) {
|
| + // If we are connection level flow control blocked, then only allow the
|
| + // crypto and headers streams to try writing as all other streams will be
|
| + // blocked.
|
| + num_writes = 0;
|
| + if (write_blocked_streams_.crypto_stream_blocked()) {
|
| + num_writes += 1;
|
| + }
|
| + if (write_blocked_streams_.headers_stream_blocked()) {
|
| + num_writes += 1;
|
| + }
|
| + }
|
| if (num_writes == 0) {
|
| return;
|
| }
|
| @@ -285,7 +298,8 @@ void QuicSession::OnCanWrite() {
|
| QuicConnection::ScopedPacketBundler ack_bundler(
|
| connection_.get(), QuicConnection::NO_ACK);
|
| for (size_t i = 0; i < num_writes; ++i) {
|
| - if (!write_blocked_streams_.HasWriteBlockedStreams()) {
|
| + if (!(write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() ||
|
| + write_blocked_streams_.HasWriteBlockedDataStreams())) {
|
| // Writing one stream removed another!? Something's broken.
|
| LOG(DFATAL) << "WriteBlockedStream is missing";
|
| connection_->CloseConnection(QUIC_INTERNAL_ERROR, false);
|
| @@ -307,8 +321,14 @@ void QuicSession::OnCanWrite() {
|
| }
|
| }
|
|
|
| -bool QuicSession::HasPendingWrites() const {
|
| - return write_blocked_streams_.HasWriteBlockedStreams();
|
| +bool QuicSession::WillingAndAbleToWrite() const {
|
| + // If the crypto or headers streams are blocked, we want to schedule a write -
|
| + // they don't get blocked by connection level flow control. Otherwise only
|
| + // schedule a write if we are not flow control blocked at the connection
|
| + // level.
|
| + return write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() ||
|
| + (!flow_controller_->IsBlocked() &&
|
| + write_blocked_streams_.HasWriteBlockedDataStreams());
|
| }
|
|
|
| bool QuicSession::HasPendingHandshake() const {
|
| @@ -604,8 +624,9 @@ void QuicSession::MarkWriteBlocked(QuicStreamId id, QuicPriority priority) {
|
| }
|
|
|
| bool QuicSession::HasDataToWrite() const {
|
| - return write_blocked_streams_.HasWriteBlockedStreams() ||
|
| - connection_->HasQueuedData();
|
| + return write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() ||
|
| + write_blocked_streams_.HasWriteBlockedDataStreams() ||
|
| + connection_->HasQueuedData();
|
| }
|
|
|
| bool QuicSession::GetSSLInfo(SSLInfo* ssl_info) const {
|
|
|