1 // Copyright 2013 The Chromium Authors 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/memory/weak_ptr.h" 12 #include "net/base/net_export.h" 13 #include "net/base/request_priority.h" 14 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h" 15 #include "net/traffic_annotation/network_traffic_annotation.h" 16 17 namespace net { 18 19 // Returns whether this frame type is subject to caps on how many 20 // frames can be queued at any given time. 21 NET_EXPORT_PRIVATE bool IsSpdyFrameTypeWriteCapped( 22 spdy::SpdyFrameType frame_type); 23 24 class SpdyBufferProducer; 25 class SpdyStream; 26 27 // A queue of SpdyBufferProducers to produce frames to write. Ordered 28 // by priority, and then FIFO. 29 class NET_EXPORT_PRIVATE SpdyWriteQueue { 30 public: 31 SpdyWriteQueue(); 32 33 SpdyWriteQueue(const SpdyWriteQueue&) = delete; 34 SpdyWriteQueue& operator=(const SpdyWriteQueue&) = delete; 35 36 ~SpdyWriteQueue(); 37 38 // Returns whether there is anything in the write queue, 39 // i.e. whether the next call to Dequeue will return true. 40 bool IsEmpty() const; 41 42 // Enqueues the given frame producer of the given type at the given 43 // priority associated with the given stream, which may be NULL if 44 // the frame producer is not associated with a stream. If |stream| 45 // is non-NULL, its priority must be equal to |priority|, and it 46 // must remain non-NULL until the write is dequeued or removed. 47 void Enqueue(RequestPriority priority, 48 spdy::SpdyFrameType frame_type, 49 std::unique_ptr<SpdyBufferProducer> frame_producer, 50 const base::WeakPtr<SpdyStream>& stream, 51 const NetworkTrafficAnnotationTag& traffic_annotation); 52 53 // Dequeues the frame producer with the highest priority that was 54 // enqueued the earliest and its associated stream. Returns true and 55 // fills in |frame_type|, |frame_producer|, and |stream| if 56 // successful -- otherwise, just returns false. 57 bool Dequeue(spdy::SpdyFrameType* frame_type, 58 std::unique_ptr<SpdyBufferProducer>* frame_producer, 59 base::WeakPtr<SpdyStream>* stream, 60 MutableNetworkTrafficAnnotationTag* traffic_annotation); 61 62 // Removes all pending writes for the given stream, which must be 63 // non-NULL. 64 void RemovePendingWritesForStream(SpdyStream* stream); 65 66 // Removes all pending writes for streams after |last_good_stream_id| 67 // and streams with no stream id. 68 void RemovePendingWritesForStreamsAfter( 69 spdy::SpdyStreamId last_good_stream_id); 70 71 // Change priority of all pending writes for the given stream. Frames will be 72 // queued after other writes with |new_priority|. 73 void ChangePriorityOfWritesForStream(SpdyStream* stream, 74 RequestPriority old_priority, 75 RequestPriority new_priority); 76 77 // Removes all pending writes. 78 void Clear(); 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 100 PendingWrite(const PendingWrite&) = delete; 101 PendingWrite& operator=(const PendingWrite&) = delete; 102 103 PendingWrite(PendingWrite&& other); 104 PendingWrite& operator=(PendingWrite&& other); 105 106 ~PendingWrite(); 107 }; 108 109 bool removing_writes_ = false; 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 118 } // namespace net 119 120 #endif // NET_SPDY_SPDY_WRITE_QUEUE_H_ 121