// Copyright 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_CORE_QUIC_DATAGRAM_QUEUE_H_ #define QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_ #include #include "absl/types/optional.h" #include "quiche/quic/core/quic_time.h" #include "quiche/quic/core/quic_types.h" #include "quiche/common/platform/api/quiche_mem_slice.h" #include "quiche/common/quiche_circular_deque.h" namespace quic { class QuicSession; // Provides a way to buffer QUIC datagrams (messages) in case they cannot // be sent due to congestion control. Datagrams are buffered for a limited // amount of time, and deleted after that time passes. class QUIC_EXPORT_PRIVATE QuicDatagramQueue { public: // An interface used to monitor events on the associated `QuicDatagramQueue`. class QUIC_EXPORT_PRIVATE Observer { public: virtual ~Observer() = default; // Called when a datagram in the associated queue is sent or discarded. // Identity information for the datagram is not given, because the sending // and discarding order is always first-in-first-out. // This function is called synchronously in `QuicDatagramQueue` methods. // `status` is nullopt when the datagram is dropped due to being in the // queue for too long. virtual void OnDatagramProcessed(absl::optional status) = 0; }; // |session| is not owned and must outlive this object. explicit QuicDatagramQueue(QuicSession* session); // |session| is not owned and must outlive this object. QuicDatagramQueue(QuicSession* session, std::unique_ptr observer); // Adds the datagram to the end of the queue. May send it immediately; if // not, MESSAGE_STATUS_BLOCKED is returned. MessageStatus SendOrQueueDatagram(quiche::QuicheMemSlice datagram); // Attempts to send a single datagram from the queue. Returns the result of // SendMessage(), or nullopt if there were no unexpired datagrams to send. absl::optional TrySendingNextDatagram(); // Sends all of the unexpired datagrams until either the connection becomes // write-blocked or the queue is empty. Returns the number of datagrams sent. size_t SendDatagrams(); // Returns the amount of time a datagram is allowed to be in the queue before // it is dropped. If not set explicitly using SetMaxTimeInQueue(), an // RTT-based heuristic is used. QuicTime::Delta GetMaxTimeInQueue() const; void SetMaxTimeInQueue(QuicTime::Delta max_time_in_queue) { max_time_in_queue_ = max_time_in_queue; } size_t queue_size() { return queue_.size(); } bool empty() { return queue_.empty(); } private: struct QUIC_EXPORT_PRIVATE Datagram { quiche::QuicheMemSlice datagram; QuicTime expiry; }; // Removes expired datagrams from the front of the queue. void RemoveExpiredDatagrams(); QuicSession* session_; // Not owned. const QuicClock* clock_; QuicTime::Delta max_time_in_queue_ = QuicTime::Delta::Zero(); quiche::QuicheCircularDeque queue_; std::unique_ptr observer_; }; } // namespace quic #endif // QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_