1 // Copyright (c) 2019 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 QUICHE_QUIC_CORE_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_ 6 #define QUICHE_QUIC_CORE_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_ 7 8 #include "absl/base/optimization.h" 9 #include "quiche/quic/core/quic_linux_socket_utils.h" 10 #include "quiche/quic/core/quic_packet_writer.h" 11 #include "quiche/quic/platform/api/quic_ip_address.h" 12 #include "quiche/quic/platform/api/quic_socket_address.h" 13 #include "quiche/common/quiche_circular_deque.h" 14 15 namespace quic { 16 17 // QuicBatchWriterBuffer manages an internal buffer to hold data from multiple 18 // packets. Packet data are placed continuously within the internal buffer such 19 // that they can be sent by a QuicGsoBatchWriter. 20 // This class can also be used by a QuicBatchWriter which uses sendmmsg, 21 // although it is not optimized for that use case. 22 class QUICHE_EXPORT QuicBatchWriterBuffer { 23 public: 24 QuicBatchWriterBuffer(); 25 26 // Clear all buffered writes, but leave the internal buffer intact. 27 void Clear(); 28 29 char* GetNextWriteLocation() const; 30 31 // Push a buffered write to the back. 32 struct QUICHE_EXPORT PushResult { 33 bool succeeded; 34 // True in one of the following cases: 35 // 1) The packet buffer is external and copied to the internal buffer, or 36 // 2) The packet buffer is from the internal buffer and moved within it. 37 // This only happens if PopBufferedWrite is called in the middle of a 38 // in-place push. 39 // Only valid if |succeeded| is true. 40 bool buffer_copied; 41 // The batch ID of the packet. Only valid if |succeeded|. 42 uint32_t batch_id = 0; 43 }; 44 45 PushResult PushBufferedWrite(const char* buffer, size_t buf_len, 46 const QuicIpAddress& self_address, 47 const QuicSocketAddress& peer_address, 48 const PerPacketOptions* options, 49 const QuicPacketWriterParams& params, 50 uint64_t release_time); 51 52 void UndoLastPush(); 53 54 // Pop |num_buffered_writes| buffered writes from the front. 55 // |num_buffered_writes| will be capped to [0, buffered_writes().size()] 56 // before it is used. 57 struct QUICHE_EXPORT PopResult { 58 int32_t num_buffers_popped; 59 // True if after |num_buffers_popped| buffers are popped from front, the 60 // remaining buffers are moved to the beginning of the internal buffer. 61 // This should normally be false. 62 bool moved_remaining_buffers; 63 }; 64 PopResult PopBufferedWrite(int32_t num_buffered_writes); 65 buffered_writes()66 const quiche::QuicheCircularDeque<BufferedWrite>& buffered_writes() const { 67 return buffered_writes_; 68 } 69 IsExternalBuffer(const char * buffer,size_t buf_len)70 bool IsExternalBuffer(const char* buffer, size_t buf_len) const { 71 return (buffer + buf_len) <= buffer_ || buffer >= buffer_end(); 72 } IsInternalBuffer(const char * buffer,size_t buf_len)73 bool IsInternalBuffer(const char* buffer, size_t buf_len) const { 74 return buffer >= buffer_ && (buffer + buf_len) <= buffer_end(); 75 } 76 77 // Number of bytes used in |buffer_|. 78 // PushBufferedWrite() increases this; PopBufferedWrite decreases this. 79 size_t SizeInUse() const; 80 81 // Rounded up from |kMaxGsoPacketSize|, which is the maximum allowed 82 // size of a GSO packet. 83 static const size_t kBufferSize = 64 * 1024; 84 85 std::string DebugString() const; 86 87 protected: 88 // Whether the invariants of the buffer are upheld. For debug & test only. 89 bool Invariants() const; buffer_end()90 const char* buffer_end() const { return buffer_ + sizeof(buffer_); } 91 ABSL_CACHELINE_ALIGNED char buffer_[kBufferSize]; 92 quiche::QuicheCircularDeque<BufferedWrite> buffered_writes_; 93 // 0 if a batch has never started. Otherwise 94 // - If |buffered_writes_| is empty, this is the ID of the previous batch. 95 // - If |buffered_writes_| is not empty, this is the ID of the current batch. 96 // For debugging only. 97 uint32_t batch_id_ = 0; 98 }; 99 100 } // namespace quic 101 102 #endif // QUICHE_QUIC_CORE_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_ 103