1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_SPDY_SPDY_WRITE_QUEUE_H_ 6 #define NET_SPDY_SPDY_WRITE_QUEUE_H_ 7 8 #include <memory> 9 10 #include "base/containers/circular_deque.h" 11 #include "base/macros.h" 12 #include "base/memory/weak_ptr.h" 13 #include "net/base/net_export.h" 14 #include "net/base/request_priority.h" 15 #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h" 16 #include "net/traffic_annotation/network_traffic_annotation.h" 17 18 namespace net { 19 20 // Returns whether this frame type is subject to caps on how many 21 // frames can be queued at any given time. 22 NET_EXPORT_PRIVATE bool IsSpdyFrameTypeWriteCapped( 23 spdy::SpdyFrameType frame_type); 24 25 class SpdyBufferProducer; 26 class SpdyStream; 27 28 // A queue of SpdyBufferProducers to produce frames to write. Ordered 29 // by priority, and then FIFO. 30 class NET_EXPORT_PRIVATE SpdyWriteQueue { 31 public: 32 SpdyWriteQueue(); 33 ~SpdyWriteQueue(); 34 35 // Returns whether there is anything in the write queue, 36 // i.e. whether the next call to Dequeue will return true. 37 bool IsEmpty() const; 38 39 // Enqueues the given frame producer of the given type at the given 40 // priority associated with the given stream, which may be NULL if 41 // the frame producer is not associated with a stream. If |stream| 42 // is non-NULL, its priority must be equal to |priority|, and it 43 // must remain non-NULL until the write is dequeued or removed. 44 void Enqueue(RequestPriority priority, 45 spdy::SpdyFrameType frame_type, 46 std::unique_ptr<SpdyBufferProducer> frame_producer, 47 const base::WeakPtr<SpdyStream>& stream, 48 const NetworkTrafficAnnotationTag& traffic_annotation); 49 50 // Dequeues the frame producer with the highest priority that was 51 // enqueued the earliest and its associated stream. Returns true and 52 // fills in |frame_type|, |frame_producer|, and |stream| if 53 // successful -- otherwise, just returns false. 54 bool Dequeue(spdy::SpdyFrameType* frame_type, 55 std::unique_ptr<SpdyBufferProducer>* frame_producer, 56 base::WeakPtr<SpdyStream>* stream, 57 MutableNetworkTrafficAnnotationTag* traffic_annotation); 58 59 // Removes all pending writes for the given stream, which must be 60 // non-NULL. 61 void RemovePendingWritesForStream(SpdyStream* stream); 62 63 // Removes all pending writes for streams after |last_good_stream_id| 64 // and streams with no stream id. 65 void RemovePendingWritesForStreamsAfter( 66 spdy::SpdyStreamId last_good_stream_id); 67 68 // Change priority of all pending writes for the given stream. Frames will be 69 // queued after other writes with |new_priority|. 70 void ChangePriorityOfWritesForStream(SpdyStream* stream, 71 RequestPriority old_priority, 72 RequestPriority new_priority); 73 74 // Removes all pending writes. 75 void Clear(); 76 77 // Returns the estimate of dynamically allocated memory in bytes. 78 size_t EstimateMemoryUsage() const; 79 80 // Returns the number of currently queued capped frames including all 81 // priorities. num_queued_capped_frames()82 int num_queued_capped_frames() const { return num_queued_capped_frames_; } 83 84 private: 85 // A struct holding a frame producer and its associated stream. 86 struct PendingWrite { 87 spdy::SpdyFrameType frame_type; 88 std::unique_ptr<SpdyBufferProducer> frame_producer; 89 base::WeakPtr<SpdyStream> stream; 90 MutableNetworkTrafficAnnotationTag traffic_annotation; 91 // Whether |stream| was non-NULL when enqueued. 92 bool has_stream; 93 94 PendingWrite(); 95 PendingWrite(spdy::SpdyFrameType frame_type, 96 std::unique_ptr<SpdyBufferProducer> frame_producer, 97 const base::WeakPtr<SpdyStream>& stream, 98 const MutableNetworkTrafficAnnotationTag& traffic_annotation); 99 ~PendingWrite(); 100 PendingWrite(PendingWrite&& other); 101 PendingWrite& operator=(PendingWrite&& other); 102 103 size_t EstimateMemoryUsage() const; 104 105 private: 106 DISALLOW_COPY_AND_ASSIGN(PendingWrite); 107 }; 108 109 bool removing_writes_; 110 111 // Number of currently queued capped frames including all priorities. 112 int num_queued_capped_frames_ = 0; 113 114 // The actual write queue, binned by priority. 115 base::circular_deque<PendingWrite> queue_[NUM_PRIORITIES]; 116 117 DISALLOW_COPY_AND_ASSIGN(SpdyWriteQueue); 118 }; 119 120 } // namespace net 121 122 #endif // NET_SPDY_SPDY_WRITE_QUEUE_H_ 123