#ifndef NET_SPDY_SPDY_WRITE_QUEUE_H_
#define NET_SPDY_SPDY_WRITE_QUEUE_H_
#include <array>
#include <memory>
#include "base/containers/circular_deque.h"
#include "base/memory/weak_ptr.h"
#include "net/base/net_export.h"
#include "net/base/request_priority.h"
#include "net/third_party/quiche/src/quiche/http2/core/spdy_protocol.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
namespace net {
NET_EXPORT_PRIVATE bool IsSpdyFrameTypeWriteCapped(
spdy::SpdyFrameType frame_type);
class SpdyBufferProducer;
class SpdyStream;
class NET_EXPORT_PRIVATE SpdyWriteQueue {
public:
SpdyWriteQueue();
SpdyWriteQueue(const SpdyWriteQueue&) = delete;
SpdyWriteQueue& operator=(const SpdyWriteQueue&) = delete;
~SpdyWriteQueue();
bool IsEmpty() const;
void Enqueue(RequestPriority priority,
spdy::SpdyFrameType frame_type,
std::unique_ptr<SpdyBufferProducer> frame_producer,
const base::WeakPtr<SpdyStream>& stream,
const NetworkTrafficAnnotationTag& traffic_annotation);
bool Dequeue(spdy::SpdyFrameType* frame_type,
std::unique_ptr<SpdyBufferProducer>* frame_producer,
base::WeakPtr<SpdyStream>* stream,
MutableNetworkTrafficAnnotationTag* traffic_annotation);
void RemovePendingWritesForStream(SpdyStream* stream);
void RemovePendingWritesForStreamsAfter(
spdy::SpdyStreamId last_good_stream_id);
void ChangePriorityOfWritesForStream(SpdyStream* stream,
RequestPriority old_priority,
RequestPriority new_priority);
void Clear();
int num_queued_capped_frames() const { return num_queued_capped_frames_; }
private:
struct PendingWrite {
spdy::SpdyFrameType frame_type;
std::unique_ptr<SpdyBufferProducer> frame_producer;
base::WeakPtr<SpdyStream> stream;
MutableNetworkTrafficAnnotationTag traffic_annotation;
bool has_stream;
PendingWrite();
PendingWrite(spdy::SpdyFrameType frame_type,
std::unique_ptr<SpdyBufferProducer> frame_producer,
const base::WeakPtr<SpdyStream>& stream,
const MutableNetworkTrafficAnnotationTag& traffic_annotation);
PendingWrite(const PendingWrite&) = delete;
PendingWrite& operator=(const PendingWrite&) = delete;
PendingWrite(PendingWrite&& other);
PendingWrite& operator=(PendingWrite&& other);
~PendingWrite();
};
bool removing_writes_ = false;
int num_queued_capped_frames_ = 0;
std::array<base::circular_deque<PendingWrite>, NUM_PRIORITIES> queue_;
};
}
#endif