blob: 7120c51ed4ce676f7a43c43525d9da79c03c03ca [file] [log] [blame]
// 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 <memory>
#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<MessageStatus> 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> 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<MessageStatus> 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<Datagram> queue_;
std::unique_ptr<Observer> observer_;
};
} // namespace quic
#endif // QUICHE_QUIC_CORE_QUIC_DATAGRAM_QUEUE_H_