xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_datagram_queue.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 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_QUIC_DATAGRAM_QUEUE_H_
6 #define QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
7 
8 #include <cstdint>
9 #include <memory>
10 #include <optional>
11 
12 #include "quiche/quic/core/quic_time.h"
13 #include "quiche/quic/core/quic_types.h"
14 #include "quiche/common/platform/api/quiche_mem_slice.h"
15 #include "quiche/common/quiche_circular_deque.h"
16 
17 namespace quic {
18 
19 class QuicSession;
20 
21 // Provides a way to buffer QUIC datagrams (messages) in case they cannot
22 // be sent due to congestion control.  Datagrams are buffered for a limited
23 // amount of time, and deleted after that time passes.
24 class QUICHE_EXPORT QuicDatagramQueue {
25  public:
26   // An interface used to monitor events on the associated `QuicDatagramQueue`.
27   class QUICHE_EXPORT Observer {
28    public:
29     virtual ~Observer() = default;
30 
31     // Called when a datagram in the associated queue is sent or discarded.
32     // Identity information for the datagram is not given, because the sending
33     // and discarding order is always first-in-first-out.
34     // This function is called synchronously in `QuicDatagramQueue` methods.
35     // `status` is nullopt when the datagram is dropped due to being in the
36     // queue for too long.
37     virtual void OnDatagramProcessed(std::optional<MessageStatus> status) = 0;
38   };
39 
40   // |session| is not owned and must outlive this object.
41   explicit QuicDatagramQueue(QuicSession* session);
42 
43   // |session| is not owned and must outlive this object.
44   QuicDatagramQueue(QuicSession* session, std::unique_ptr<Observer> observer);
45 
46   // Adds the datagram to the end of the queue.  May send it immediately; if
47   // not, MESSAGE_STATUS_BLOCKED is returned.
48   MessageStatus SendOrQueueDatagram(quiche::QuicheMemSlice datagram);
49 
50   // Attempts to send a single datagram from the queue.  Returns the result of
51   // SendMessage(), or nullopt if there were no unexpired datagrams to send.
52   std::optional<MessageStatus> TrySendingNextDatagram();
53 
54   // Sends all of the unexpired datagrams until either the connection becomes
55   // write-blocked or the queue is empty.  Returns the number of datagrams sent.
56   size_t SendDatagrams();
57 
58   // Returns the amount of time a datagram is allowed to be in the queue before
59   // it is dropped.  If not set explicitly using SetMaxTimeInQueue(), an
60   // RTT-based heuristic is used.
61   QuicTime::Delta GetMaxTimeInQueue() const;
62 
SetMaxTimeInQueue(QuicTime::Delta max_time_in_queue)63   void SetMaxTimeInQueue(QuicTime::Delta max_time_in_queue) {
64     max_time_in_queue_ = max_time_in_queue;
65   }
66 
67   // If set to true, all datagrams added into the queue would be sent with the
68   // flush flag set to true, meaning that they will bypass congestion control
69   // and related logic.
SetForceFlush(bool force_flush)70   void SetForceFlush(bool force_flush) { force_flush_ = force_flush; }
71 
queue_size()72   size_t queue_size() { return queue_.size(); }
empty()73   bool empty() { return queue_.empty(); }
expired_datagram_count()74   uint64_t expired_datagram_count() const { return expired_datagram_count_; }
75 
76  private:
77   struct QUICHE_EXPORT Datagram {
78     quiche::QuicheMemSlice datagram;
79     QuicTime expiry;
80   };
81 
82   // Removes expired datagrams from the front of the queue.
83   void RemoveExpiredDatagrams();
84 
85   QuicSession* session_;  // Not owned.
86   const QuicClock* clock_;
87 
88   QuicTime::Delta max_time_in_queue_ = QuicTime::Delta::Zero();
89   quiche::QuicheCircularDeque<Datagram> queue_;
90   std::unique_ptr<Observer> observer_;
91   uint64_t expired_datagram_count_ = 0;
92   bool force_flush_ = false;
93 };
94 
95 }  // namespace quic
96 
97 #endif  // QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_
98