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