summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/batch_writer/quic_batch_writer_buffer.h
blob: 88183f366b3f5b2ca7efa2b51332c86aaccb8d5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_
#define QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_

#include "absl/base/optimization.h"
#include "net/third_party/quiche/src/quic/core/quic_circular_deque.h"
#include "net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h"
#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"

namespace quic {

// QuicBatchWriterBuffer manages an internal buffer to hold data from multiple
// packets. Packet data are placed continuously within the internal buffer such
// that they can be sent by a QuicGsoBatchWriter.
// This class can also be used by a QuicBatchWriter which uses sendmmsg,
// although it is not optimized for that use case.
class QUIC_EXPORT_PRIVATE QuicBatchWriterBuffer {
 public:
  QuicBatchWriterBuffer();

  // Clear all buffered writes, but leave the internal buffer intact.
  void Clear();

  char* GetNextWriteLocation() const;

  // Push a buffered write to the back.
  struct QUIC_EXPORT_PRIVATE PushResult {
    bool succeeded;
    // True in one of the following cases:
    // 1) The packet buffer is external and copied to the internal buffer, or
    // 2) The packet buffer is from the internal buffer and moved within it.
    //    This only happens if PopBufferedWrite is called in the middle of a
    //    in-place push.
    // Only valid if |succeeded| is true.
    bool buffer_copied;
  };

  PushResult PushBufferedWrite(const char* buffer,
                               size_t buf_len,
                               const QuicIpAddress& self_address,
                               const QuicSocketAddress& peer_address,
                               const PerPacketOptions* options,
                               uint64_t release_time);

  void UndoLastPush();

  // Pop |num_buffered_writes| buffered writes from the front.
  // |num_buffered_writes| will be capped to [0, buffered_writes().size()]
  // before it is used.
  struct QUIC_EXPORT_PRIVATE PopResult {
    int32_t num_buffers_popped;
    // True if after |num_buffers_popped| buffers are popped from front, the
    // remaining buffers are moved to the beginning of the internal buffer.
    // This should normally be false.
    bool moved_remaining_buffers;
  };
  PopResult PopBufferedWrite(int32_t num_buffered_writes);

  const QuicCircularDeque<BufferedWrite>& buffered_writes() const {
    return buffered_writes_;
  }

  bool IsExternalBuffer(const char* buffer, size_t buf_len) const {
    return (buffer + buf_len) <= buffer_ || buffer >= buffer_end();
  }
  bool IsInternalBuffer(const char* buffer, size_t buf_len) const {
    return buffer >= buffer_ && (buffer + buf_len) <= buffer_end();
  }

  // Number of bytes used in |buffer_|.
  // PushBufferedWrite() increases this; PopBufferedWrite decreases this.
  size_t SizeInUse() const;

  // Rounded up from |kMaxGsoPacketSize|, which is the maximum allowed
  // size of a GSO packet.
  static const size_t kBufferSize = 64 * 1024;

  std::string DebugString() const;

 protected:
  // Whether the invariants of the buffer are upheld. For debug & test only.
  bool Invariants() const;
  const char* buffer_end() const { return buffer_ + sizeof(buffer_); }
  ABSL_CACHELINE_ALIGNED char buffer_[kBufferSize];
  QuicCircularDeque<BufferedWrite> buffered_writes_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_PLATFORM_IMPL_BATCH_WRITER_QUIC_BATCH_WRITER_BUFFER_H_