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