| Index: net/quic/quic_write_blocked_list.h
|
| diff --git a/net/quic/quic_write_blocked_list.h b/net/quic/quic_write_blocked_list.h
|
| index 3c08badd6162d03d9e3ca605712c1cb3376a17a2..63580f857bf089a92079c37082d1c2a98906a85c 100644
|
| --- a/net/quic/quic_write_blocked_list.h
|
| +++ b/net/quic/quic_write_blocked_list.h
|
| @@ -8,6 +8,7 @@
|
| #include <set>
|
|
|
| #include "net/base/net_export.h"
|
| +#include "net/quic/quic_flags.h"
|
| #include "net/quic/quic_protocol.h"
|
| #include "net/spdy/write_blocked_list.h"
|
|
|
| @@ -21,8 +22,10 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
|
| typedef WriteBlockedList<QuicStreamId> QuicWriteBlockedListBase;
|
|
|
| public:
|
| - static const QuicPriority kHighestPriority;
|
| - static const QuicPriority kLowestPriority;
|
| + static const QuicPriority kHighestPriority =
|
| + static_cast<QuicPriority>(net::kHighestPriority);
|
| + static const QuicPriority kLowestPriority =
|
| + static_cast<QuicPriority>(net::kLowestPriority);
|
|
|
| QuicWriteBlockedList();
|
| ~QuicWriteBlockedList();
|
| @@ -47,6 +50,8 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
|
| return num_blocked;
|
| }
|
|
|
| + // Pops the highest priorty stream, special casing crypto and headers streams.
|
| + // Latches the most recently popped data stream for batch writing purposes.
|
| QuicStreamId PopFront() {
|
| if (crypto_stream_blocked_) {
|
| crypto_stream_blocked_ = false;
|
| @@ -61,10 +66,44 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
|
| SpdyPriority priority =
|
| base_write_blocked_list_.GetHighestPriorityWriteBlockedList();
|
| QuicStreamId id = base_write_blocked_list_.PopFront(priority);
|
| +
|
| + if (base_write_blocked_list_.NumBlockedStreams(priority) == 0) {
|
| + // If no streams are blocked, don't bother latching. This stream will be
|
| + // the first popped for its priority anyway.
|
| + batch_write_stream_id_[priority] = 0;
|
| + } else if (batch_write_stream_id_[priority] != id) {
|
| + // If newly latching this batch write stream, let it write 16k.
|
| + batch_write_stream_id_[priority] = id;
|
| + bytes_left_for_batch_write_[priority] = 16000;
|
| + last_priority_popped_ = priority;
|
| + }
|
| +
|
| return id;
|
| }
|
|
|
| - void PushBack(QuicStreamId stream_id, QuicPriority priority) {
|
| + void UpdateBytesForStream(QuicStreamId stream_id, size_t bytes) {
|
| + if (batch_write_stream_id_[last_priority_popped_] == stream_id) {
|
| + // If this was the last data stream popped by PopFront, update the
|
| + // bytes remaining in its batch write.
|
| + bytes_left_for_batch_write_[last_priority_popped_] -= bytes;
|
| + } else {
|
| + // If a batch write stream was set, it should only be preempted by the
|
| + // crypto or headers streams. Any higher priority data stream would
|
| + // *become* the new batch write stream.
|
| + if (FLAGS_respect_send_alarm &&
|
| + FLAGS_quic_batch_writes) {
|
| + DCHECK(stream_id == kCryptoStreamId || stream_id == kHeadersStreamId ||
|
| + batch_write_stream_id_[last_priority_popped_] == 0 ||
|
| + bytes == 0);
|
| + }
|
| + }
|
| + }
|
| +
|
| + // Pushes a stream to the back of the std::list for this priority level *unless* it
|
| + // is latched for doing batched writes in which case it goes to the front of
|
| + // the std::list for this priority level.
|
| + // Headers and crypto streams are special cased to always resume first.
|
| + void AddStream(QuicStreamId stream_id, QuicPriority priority) {
|
| if (stream_id == kCryptoStreamId) {
|
| DCHECK_EQ(kHighestPriority, priority);
|
| // TODO(avd) Add DCHECK(!crypto_stream_blocked_)
|
| @@ -78,9 +117,17 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
|
| headers_stream_blocked_ = true;
|
| return;
|
| }
|
| -
|
| - base_write_blocked_list_.PushBack(
|
| - stream_id, static_cast<SpdyPriority>(priority));
|
| + if (FLAGS_quic_batch_writes &&
|
| + stream_id == batch_write_stream_id_[last_priority_popped_] &&
|
| + bytes_left_for_batch_write_[last_priority_popped_] > 0) {
|
| + // If the batch write stream has more data to write, push it to the front
|
| + // for its priority level.
|
| + base_write_blocked_list_.PushFront(
|
| + stream_id, static_cast<SpdyPriority>(priority));
|
| + } else {
|
| + base_write_blocked_list_.PushBack(
|
| + stream_id, static_cast<SpdyPriority>(priority));
|
| + }
|
| return;
|
| }
|
|
|
| @@ -89,6 +136,19 @@ class NET_EXPORT_PRIVATE QuicWriteBlockedList {
|
|
|
| private:
|
| QuicWriteBlockedListBase base_write_blocked_list_;
|
| +
|
| + // If performing batch writes, this will be the stream ID of the stream doing
|
| + // batch writes for this priority level. We will allow this stream to write
|
| + // until it has written kBatchWriteSize bytes, it has no more data to write,
|
| + // or a higher priority stream preempts.
|
| + QuicStreamId batch_write_stream_id_[kLowestPriority + 1];
|
| + // Set to kBatchWriteSize when we set a new batch_write_stream_id_ for a given
|
| + // priority. This is decremented with each write the stream does until it is
|
| + // done with its batch write.
|
| + int32 bytes_left_for_batch_write_[kLowestPriority + 1];
|
| + // Tracks the last priority popped for UpdateBytesForStream.
|
| + QuicPriority last_priority_popped_;
|
| +
|
| bool crypto_stream_blocked_;
|
| bool headers_stream_blocked_;
|
|
|
|
|