• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 QUIC_EXPORT_PRIVATE 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 QUIC_EXPORT_PRIVATE 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   };
42 
43   PushResult PushBufferedWrite(const char* buffer, size_t buf_len,
44                                const QuicIpAddress& self_address,
45                                const QuicSocketAddress& peer_address,
46                                const PerPacketOptions* options,
47                                uint64_t release_time);
48 
49   void UndoLastPush();
50 
51   // Pop |num_buffered_writes| buffered writes from the front.
52   // |num_buffered_writes| will be capped to [0, buffered_writes().size()]
53   // before it is used.
54   struct QUIC_EXPORT_PRIVATE PopResult {
55     int32_t num_buffers_popped;
56     // True if after |num_buffers_popped| buffers are popped from front, the
57     // remaining buffers are moved to the beginning of the internal buffer.
58     // This should normally be false.
59     bool moved_remaining_buffers;
60   };
61   PopResult PopBufferedWrite(int32_t num_buffered_writes);
62 
buffered_writes()63   const quiche::QuicheCircularDeque<BufferedWrite>& buffered_writes() const {
64     return buffered_writes_;
65   }
66 
IsExternalBuffer(const char * buffer,size_t buf_len)67   bool IsExternalBuffer(const char* buffer, size_t buf_len) const {
68     return (buffer + buf_len) <= buffer_ || buffer >= buffer_end();
69   }
IsInternalBuffer(const char * buffer,size_t buf_len)70   bool IsInternalBuffer(const char* buffer, size_t buf_len) const {
71     return buffer >= buffer_ && (buffer + buf_len) <= buffer_end();
72   }
73 
74   // Number of bytes used in |buffer_|.
75   // PushBufferedWrite() increases this; PopBufferedWrite decreases this.
76   size_t SizeInUse() const;
77 
78   // Rounded up from |kMaxGsoPacketSize|, which is the maximum allowed
79   // size of a GSO packet.
80   static const size_t kBufferSize = 64 * 1024;
81 
82   std::string DebugString() const;
83 
84  protected:
85   // Whether the invariants of the buffer are upheld. For debug & test only.
86   bool Invariants() const;
buffer_end()87   const char* buffer_end() const { return buffer_ + sizeof(buffer_); }
88   ABSL_CACHELINE_ALIGNED char buffer_[kBufferSize];
89   quiche::QuicheCircularDeque<BufferedWrite> buffered_writes_;
90 };
91 
92 }  // namespace quic
93 
94 #endif  // QUICHE_QUIC_CORE_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
95